mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
sys, dll: QuerySecurity, SetSecurity
This commit is contained in:
parent
12bbddfb19
commit
7e90092028
@ -153,7 +153,7 @@ typedef struct
|
||||
UINT32 FileAttributes; /* file attributes for new files */
|
||||
FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; /* security descriptor for new files */
|
||||
UINT64 AllocationSize; /* initial allocation size */
|
||||
UINT64 AccessToken; /* (HANDLE); request access token; sent if NoAccessCheck is 0 */
|
||||
UINT64 AccessToken; /* request access token (HANDLE) */
|
||||
UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
|
||||
UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */
|
||||
FSP_FSCTL_TRANSACT_BUF Ea; /* reserved; not currently implemented */
|
||||
@ -240,6 +240,7 @@ typedef struct
|
||||
UINT64 UserContext;
|
||||
UINT64 UserContext2;
|
||||
UINT32 SecurityInformation;
|
||||
UINT64 AccessToken; /* request access token (HANDLE) */
|
||||
FSP_FSCTL_TRANSACT_BUF SecurityDescriptor;
|
||||
} SetSecurity;
|
||||
} Req;
|
||||
|
@ -95,7 +95,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
NTSTATUS (*SetSecurity)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor);
|
||||
SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor);
|
||||
} FSP_FILE_SYSTEM_INTERFACE;
|
||||
typedef struct _FSP_FILE_SYSTEM
|
||||
{
|
||||
@ -196,10 +196,14 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem,
|
||||
BOOLEAN CheckParentDirectory, BOOLEAN AllowTraverseCheck,
|
||||
UINT32 DesiredAccess, PUINT32 PGrantedAccess,
|
||||
PSECURITY_DESCRIPTOR *PSecurityDescriptor);
|
||||
FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_API NTSTATUS FspCreateSecurityDescriptor(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PSECURITY_DESCRIPTOR ParentDescriptor,
|
||||
PSECURITY_DESCRIPTOR *PSecurityDescriptor);
|
||||
FSP_API NTSTATUS FspSetSecurityDescriptor(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PSECURITY_DESCRIPTOR InputDescriptor,
|
||||
PSECURITY_DESCRIPTOR *PSecurityDescriptor);
|
||||
FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||
NTSTATUS (*CreateFunc)());
|
||||
static inline
|
||||
|
@ -47,6 +47,9 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (0 != PSecurityDescriptor)
|
||||
*PSecurityDescriptor = 0;
|
||||
|
||||
if (FspFsctlTransactCreateKind != Request->Kind)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (0 == FileSystem->Interface->GetSecurityByName ||
|
||||
(!Request->Req.Create.UserMode && 0 == PSecurityDescriptor))
|
||||
{
|
||||
@ -202,13 +205,16 @@ exit:
|
||||
return Result;
|
||||
}
|
||||
|
||||
FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_API NTSTATUS FspCreateSecurityDescriptor(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PSECURITY_DESCRIPTOR ParentDescriptor,
|
||||
PSECURITY_DESCRIPTOR *PSecurityDescriptor)
|
||||
{
|
||||
*PSecurityDescriptor = 0;
|
||||
|
||||
if (FspFsctlTransactCreateKind != Request->Kind)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (!CreatePrivateObjectSecurity(
|
||||
ParentDescriptor,
|
||||
0 != Request->Req.Create.SecurityDescriptor.Offset ?
|
||||
@ -224,11 +230,75 @@ FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
FSP_API NTSTATUS FspSetSecurityDescriptor(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PSECURITY_DESCRIPTOR InputDescriptor,
|
||||
PSECURITY_DESCRIPTOR *PSecurityDescriptor)
|
||||
{
|
||||
*PSecurityDescriptor = 0;
|
||||
|
||||
if (FspFsctlTransactSetSecurityKind != Request->Kind)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (0 == InputDescriptor)
|
||||
return STATUS_NO_SECURITY_ON_OBJECT;
|
||||
|
||||
/*
|
||||
* SetPrivateObjectSecurity is a broken API. It assumes that the passed
|
||||
* descriptor resides on memory allocated by CreatePrivateObjectSecurity
|
||||
* or SetPrivateObjectSecurity and frees the descriptor on success.
|
||||
*
|
||||
* In our case the security descriptor comes from the user mode file system,
|
||||
* which may conjure it any way it sees fit. So we have to somehow make a copy
|
||||
* of the InputDescriptor and place it in memory that SetPrivateObjectSecurity
|
||||
* can then free. To complicate matters there is no API that can be used for
|
||||
* this purpose. What a PITA!
|
||||
*/
|
||||
/* !!!: HACK! HACK! HACK!
|
||||
*
|
||||
* Turns out that SetPrivateObjectSecurity and friends really use RtlProcessHeap
|
||||
* internally, which is just another name for GetProcessHeap().
|
||||
*
|
||||
* I wish there was a cleaner way to do this!
|
||||
*/
|
||||
|
||||
HANDLE ProcessHeap = GetProcessHeap();
|
||||
DWORD InputDescriptorSize = GetSecurityDescriptorLength(InputDescriptor);
|
||||
PSECURITY_DESCRIPTOR CopiedDescriptor;
|
||||
|
||||
CopiedDescriptor = HeapAlloc(ProcessHeap, 0, InputDescriptorSize);
|
||||
if (0 == CopiedDescriptor)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
memcpy(CopiedDescriptor, InputDescriptor, InputDescriptorSize);
|
||||
InputDescriptor = CopiedDescriptor;
|
||||
|
||||
if (!SetPrivateObjectSecurity(
|
||||
Request->Req.SetSecurity.SecurityInformation,
|
||||
(PVOID)Request->Buffer,
|
||||
&InputDescriptor,
|
||||
&FspFileGenericMapping,
|
||||
(HANDLE)Request->Req.SetSecurity.AccessToken))
|
||||
{
|
||||
HeapFree(ProcessHeap, 0, CopiedDescriptor);
|
||||
return FspNtStatusFromWin32(GetLastError());
|
||||
}
|
||||
|
||||
/* CopiedDescriptor has been freed by SetPrivateObjectSecurity! */
|
||||
|
||||
*PSecurityDescriptor = InputDescriptor;
|
||||
|
||||
DEBUGLOGSD("SDDL=%s", *PSecurityDescriptor);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||
NTSTATUS(*CreateFunc)())
|
||||
NTSTATUS (*CreateFunc)())
|
||||
{
|
||||
if ((NTSTATUS (*)())FspAccessCheckEx == CreateFunc)
|
||||
MemFree(SecurityDescriptor);
|
||||
else if ((NTSTATUS (*)())FspAssignSecurity == CreateFunc)
|
||||
else
|
||||
if ((NTSTATUS (*)())FspCreateSecurityDescriptor == CreateFunc ||
|
||||
(NTSTATUS (*)())FspSetSecurityDescriptor == CreateFunc)
|
||||
DestroyPrivateObjectSecurity(&SecurityDescriptor);
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
Result = FspAssignSecurity(FileSystem, Request, ParentDescriptor, &ObjectDescriptor);
|
||||
Result = FspCreateSecurityDescriptor(FileSystem, Request, ParentDescriptor, &ObjectDescriptor);
|
||||
FspDeleteSecurityDescriptor(ParentDescriptor, FspAccessCheckEx);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
@ -94,7 +94,7 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
|
||||
&FileNode, &FileInfo);
|
||||
FspDeleteSecurityDescriptor(ObjectDescriptor, FspAssignSecurity);
|
||||
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
@ -171,7 +171,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
Result = FspAssignSecurity(FileSystem, Request, ParentDescriptor, &ObjectDescriptor);
|
||||
Result = FspCreateSecurityDescriptor(FileSystem, Request, ParentDescriptor, &ObjectDescriptor);
|
||||
FspDeleteSecurityDescriptor(ParentDescriptor, FspAccessCheckEx);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
@ -182,7 +182,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
|
||||
&FileNode, &FileInfo);
|
||||
FspDeleteSecurityDescriptor(ObjectDescriptor, FspAssignSecurity);
|
||||
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
}
|
||||
@ -261,7 +261,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
Result = FspAssignSecurity(FileSystem, Request, ParentDescriptor, &ObjectDescriptor);
|
||||
Result = FspCreateSecurityDescriptor(FileSystem, Request, ParentDescriptor, &ObjectDescriptor);
|
||||
FspDeleteSecurityDescriptor(ParentDescriptor, FspAccessCheckEx);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
@ -272,7 +272,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
|
||||
&FileNode, &FileInfo);
|
||||
FspDeleteSecurityDescriptor(ObjectDescriptor, FspAssignSecurity);
|
||||
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
}
|
||||
@ -544,22 +544,32 @@ FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||
{
|
||||
NTSTATUS Result;
|
||||
SIZE_T SecurityDescriptorSize;
|
||||
|
||||
if (0 == FileSystem->Interface->GetSecurity)
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
(VOID)Result;
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
SecurityDescriptorSize = FSP_FSCTL_TRANSACT_RSP_SIZEMAX - sizeof *Response;
|
||||
Result = FileSystem->Interface->GetSecurity(FileSystem, Request,
|
||||
(PVOID)Request->Req.QuerySecurity.UserContext,
|
||||
Response->Buffer, &SecurityDescriptorSize);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return STATUS_BUFFER_OVERFLOW != Result ? Result : STATUS_INVALID_SECURITY_DESCR;
|
||||
|
||||
Response->Size = (UINT16)(sizeof *Response + SecurityDescriptorSize);
|
||||
Response->Rsp.QuerySecurity.SecurityDescriptor.Offset = 0;
|
||||
Response->Rsp.QuerySecurity.SecurityDescriptor.Size = (UINT16)SecurityDescriptorSize;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||
{
|
||||
NTSTATUS Result;
|
||||
|
||||
if (0 == FileSystem->Interface->SetSecurity)
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
(VOID)Result;
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
return FileSystem->Interface->SetSecurity(FileSystem, Request,
|
||||
(PVOID)Request->Req.SetSecurity.UserContext,
|
||||
Request->Req.SetSecurity.SecurityInformation,
|
||||
(PSECURITY_DESCRIPTOR)Request->Buffer);
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ NTSTATUS DriverEntry(
|
||||
FspIopCompleteFunction[IRP_MJ_LOCK_CONTROL] = FspFsvolLockControlComplete;
|
||||
FspIopCompleteFunction[IRP_MJ_CLEANUP] = FspFsvolCleanupComplete;
|
||||
FspIopCompleteFunction[IRP_MJ_QUERY_SECURITY] = FspFsvolQuerySecurityComplete;
|
||||
FspIopPrepareFunction[IRP_MJ_SET_SECURITY] = FspFsvolSetSecurityPrepare;
|
||||
FspIopCompleteFunction[IRP_MJ_SET_SECURITY] = FspFsvolSetSecurityComplete;
|
||||
|
||||
/* setup fast I/O and resource acquisition */
|
||||
|
@ -258,6 +258,7 @@ FSP_IOCMPL_DISPATCH FspFsvolQueryVolumeInformationComplete;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolReadComplete;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolSetEaComplete;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolSetInformationComplete;
|
||||
FSP_IOPREP_DISPATCH FspFsvolSetSecurityPrepare;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolSetSecurityComplete;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolSetVolumeInformationComplete;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolShutdownComplete;
|
||||
|
@ -9,19 +9,23 @@
|
||||
static NTSTATUS FspFsvolQuerySecurity(
|
||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
FSP_IOCMPL_DISPATCH FspFsvolQuerySecurityComplete;
|
||||
static FSP_IOP_REQUEST_FINI FspFsvolQuerySecurityRequestFini;
|
||||
static NTSTATUS FspFsvolSetSecurity(
|
||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
FSP_IOPREP_DISPATCH FspFsvolSetSecurityPrepare;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolSetSecurityComplete;
|
||||
static FSP_IOP_REQUEST_FINI FspFsvolSecurityRequestFini;
|
||||
static FSP_IOP_REQUEST_FINI FspFsvolSetSecurityRequestFini;
|
||||
FSP_DRIVER_DISPATCH FspQuerySecurity;
|
||||
FSP_DRIVER_DISPATCH FspSetSecurity;
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FspFsvolQuerySecurity)
|
||||
#pragma alloc_text(PAGE, FspFsvolQuerySecurityComplete)
|
||||
#pragma alloc_text(PAGE, FspFsvolQuerySecurityRequestFini)
|
||||
#pragma alloc_text(PAGE, FspFsvolSetSecurity)
|
||||
#pragma alloc_text(PAGE, FspFsvolSetSecurityPrepare)
|
||||
#pragma alloc_text(PAGE, FspFsvolSetSecurityComplete)
|
||||
#pragma alloc_text(PAGE, FspFsvolSecurityRequestFini)
|
||||
#pragma alloc_text(PAGE, FspFsvolSetSecurityRequestFini)
|
||||
#pragma alloc_text(PAGE, FspQuerySecurity)
|
||||
#pragma alloc_text(PAGE, FspSetSecurity)
|
||||
#endif
|
||||
@ -34,6 +38,8 @@ enum
|
||||
|
||||
/* SetSecurity */
|
||||
//RequestFileNode = 0,
|
||||
RequestAccessToken = 2,
|
||||
RequestProcess = 3,
|
||||
};
|
||||
|
||||
static NTSTATUS FspFsvolQuerySecurity(
|
||||
@ -72,7 +78,7 @@ static NTSTATUS FspFsvolQuerySecurity(
|
||||
|
||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||
|
||||
Result = FspIopCreateRequestEx(Irp, 0, 0, FspFsvolSecurityRequestFini, &Request);
|
||||
Result = FspIopCreateRequestEx(Irp, 0, 0, FspFsvolQuerySecurityRequestFini, &Request);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
FspFileNodeRelease(FileNode, Full);
|
||||
@ -158,6 +164,16 @@ NTSTATUS FspFsvolQuerySecurityComplete(
|
||||
IrpSp->FileObject, IrpSp->Parameters.QuerySecurity.SecurityInformation);
|
||||
}
|
||||
|
||||
static VOID FspFsvolQuerySecurityRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FILE_NODE *FileNode = Context[RequestFileNode];
|
||||
|
||||
if (0 != FileNode)
|
||||
FspFileNodeReleaseOwner(FileNode, Full, Request);
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolSetSecurity(
|
||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
@ -188,7 +204,7 @@ static NTSTATUS FspFsvolSetSecurity(
|
||||
|
||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||
|
||||
Result = FspIopCreateRequestEx(Irp, 0, SecurityDescriptorSize, FspFsvolSecurityRequestFini,
|
||||
Result = FspIopCreateRequestEx(Irp, 0, SecurityDescriptorSize, FspFsvolSetSecurityRequestFini,
|
||||
&Request);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
@ -210,6 +226,53 @@ static NTSTATUS FspFsvolSetSecurity(
|
||||
return FSP_STATUS_IOQ_POST;
|
||||
}
|
||||
|
||||
NTSTATUS FspFsvolSetSecurityPrepare(
|
||||
PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
NTSTATUS Result;
|
||||
SECURITY_SUBJECT_CONTEXT SecuritySubjectContext;
|
||||
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
|
||||
SECURITY_CLIENT_CONTEXT SecurityClientContext;
|
||||
HANDLE UserModeAccessToken;
|
||||
PEPROCESS Process;
|
||||
|
||||
/* duplicate the subject context access token into an impersonation token */
|
||||
SecurityQualityOfService.Length = sizeof SecurityQualityOfService;
|
||||
SecurityQualityOfService.ImpersonationLevel = SecurityIdentification;
|
||||
SecurityQualityOfService.ContextTrackingMode = SECURITY_STATIC_TRACKING;
|
||||
SecurityQualityOfService.EffectiveOnly = FALSE;
|
||||
SeCaptureSubjectContext(&SecuritySubjectContext);
|
||||
SeLockSubjectContext(&SecuritySubjectContext);
|
||||
Result = SeCreateClientSecurityFromSubjectContext(&SecuritySubjectContext,
|
||||
&SecurityQualityOfService, FALSE, &SecurityClientContext);
|
||||
SeUnlockSubjectContext(&SecuritySubjectContext);
|
||||
SeReleaseSubjectContext(&SecuritySubjectContext);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
ASSERT(TokenImpersonation == SeTokenType(SecurityClientContext.ClientToken));
|
||||
|
||||
/* get a user-mode handle to the impersonation token */
|
||||
Result = ObOpenObjectByPointer(SecurityClientContext.ClientToken,
|
||||
0, 0, TOKEN_QUERY, *SeTokenObjectType, UserMode, &UserModeAccessToken);
|
||||
SeDeleteClientSecurity(&SecurityClientContext);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
/* get a pointer to the current process so that we can close the impersonation token later */
|
||||
Process = PsGetCurrentProcess();
|
||||
ObReferenceObject(Process);
|
||||
|
||||
/* send the user-mode handle to the user-mode file system */
|
||||
FspIopRequestContext(Request, RequestAccessToken) = UserModeAccessToken;
|
||||
FspIopRequestContext(Request, RequestProcess) = Process;
|
||||
Request->Req.SetSecurity.AccessToken = (UINT_PTR)UserModeAccessToken;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS FspFsvolSetSecurityComplete(
|
||||
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response)
|
||||
{
|
||||
@ -252,14 +315,40 @@ NTSTATUS FspFsvolSetSecurityComplete(
|
||||
IrpSp->FileObject, IrpSp->Parameters.SetSecurity.SecurityInformation);
|
||||
}
|
||||
|
||||
static VOID FspFsvolSecurityRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
|
||||
static VOID FspFsvolSetSecurityRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FILE_NODE *FileNode = Context[RequestFileNode];
|
||||
HANDLE AccessToken = Context[RequestAccessToken];
|
||||
PEPROCESS Process = Context[RequestProcess];
|
||||
|
||||
if (0 != FileNode)
|
||||
FspFileNodeReleaseOwner(FileNode, Full, Request);
|
||||
|
||||
if (0 != AccessToken)
|
||||
{
|
||||
KAPC_STATE ApcState;
|
||||
BOOLEAN Attach;
|
||||
|
||||
ASSERT(0 != Process);
|
||||
Attach = Process != PsGetCurrentProcess();
|
||||
|
||||
if (Attach)
|
||||
KeStackAttachProcess(Process, &ApcState);
|
||||
#if DBG
|
||||
NTSTATUS Result0;
|
||||
Result0 = ObCloseHandle(AccessToken, UserMode);
|
||||
if (!NT_SUCCESS(Result0))
|
||||
DEBUGLOG("ObCloseHandle() = %s", NtStatusSym(Result0));
|
||||
#else
|
||||
ObCloseHandle(AccessToken, UserMode);
|
||||
#endif
|
||||
if (Attach)
|
||||
KeUnstackDetachProcess(&ApcState);
|
||||
|
||||
ObDereferenceObject(Process);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS FspQuerySecurity(
|
||||
|
@ -553,6 +553,57 @@ NTSTATUS Rename(FSP_FILE_SYSTEM *FileSystem,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS GetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode0,
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize)
|
||||
{
|
||||
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
|
||||
|
||||
if (FileNode->FileSecuritySize > *PSecurityDescriptorSize)
|
||||
{
|
||||
*PSecurityDescriptorSize = FileNode->FileSecuritySize;
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
*PSecurityDescriptorSize = FileNode->FileSecuritySize;
|
||||
if (0 != SecurityDescriptor)
|
||||
memcpy(SecurityDescriptor, FileNode->FileSecurity, FileNode->FileSecuritySize);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS SetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode0,
|
||||
SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor)
|
||||
{
|
||||
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
|
||||
PSECURITY_DESCRIPTOR NewSecurityDescriptor, FileSecurity;
|
||||
SIZE_T FileSecuritySize;
|
||||
NTSTATUS Result;
|
||||
|
||||
Result = FspSetSecurityDescriptor(FileSystem, Request, FileNode->FileSecurity,
|
||||
&NewSecurityDescriptor);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
FileSecuritySize = GetSecurityDescriptorLength(NewSecurityDescriptor);
|
||||
FileSecurity = (PSECURITY_DESCRIPTOR)malloc(FileSecuritySize);
|
||||
if (0 == FileSecurity)
|
||||
{
|
||||
FspDeleteSecurityDescriptor(NewSecurityDescriptor, (NTSTATUS (*)())FspSetSecurityDescriptor);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
memcpy(FileSecurity, SecurityDescriptor, FileSecuritySize);
|
||||
FspDeleteSecurityDescriptor(NewSecurityDescriptor, (NTSTATUS (*)())FspSetSecurityDescriptor);
|
||||
|
||||
FileNode->FileSecuritySize = FileSecuritySize;
|
||||
FileNode->FileSecurity = FileSecurity;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
|
||||
{
|
||||
GetVolumeInfo,
|
||||
@ -569,6 +620,8 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
|
||||
SetFileSize,
|
||||
CanDelete,
|
||||
Rename,
|
||||
GetSecurity,
|
||||
SetSecurity,
|
||||
};
|
||||
|
||||
static VOID MemfsEnterOperation(FSP_FILE_SYSTEM *FileSystem,
|
||||
|
Loading…
x
Reference in New Issue
Block a user