dll: FspAccessCheck

This commit is contained in:
Bill Zissimopoulos 2016-01-01 00:37:50 -08:00
parent 223b287453
commit 2f10c07ab2
2 changed files with 89 additions and 17 deletions

View File

@ -37,10 +37,10 @@ typedef struct _FSP_FILE_SYSTEM
FSP_FILE_SYSTEM_DISPATCHER *Dispatcher;
FSP_FILE_SYSTEM_DISPATCHER *EnterOperation, *LeaveOperation;
FSP_FILE_SYSTEM_OPERATION *Operations[FspFsctlTransactKindCount];
NTSTATUS (*AccessCheck)(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *,
PDWORD);
NTSTATUS (*QuerySecurity)(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *,
SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, SIZE_T *);
NTSTATUS (*AccessCheck)(FSP_FILE_SYSTEM *,
FSP_FSCTL_TRANSACT_REQ *, DWORD, PDWORD);
NTSTATUS (*QuerySecurity)(FSP_FILE_SYSTEM *,
PWSTR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, SIZE_T *);
} FSP_FILE_SYSTEM;
FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
@ -87,6 +87,15 @@ FSP_API NTSTATUS FspSendResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_API NTSTATUS FspSendResponseWithStatus(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, NTSTATUS Result);
/*
* Access Checks
*/
FSP_API PGENERIC_MAPPING FspGetFileGenericMapping(VOID);
FSP_API NTSTATUS FspOpenAccessToken(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, PHANDLE PAccessToken);
FSP_API NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, DWORD DesiredAccess, PDWORD PGrantedAccess);
/*
* Path Handling
*/

View File

@ -25,46 +25,109 @@ FSP_API NTSTATUS FspOpenAccessToken(FSP_FILE_SYSTEM *FileSystem,
return FspFsctlOpenAccessToken(FileSystem->VolumeHandle, Request->Hint, PAccessToken);
}
#if 0
static NTSTATUS FspGetFileSecurityDescriptor(FSP_FILE_SYSTEM *FileSystem,
PWSTR FileName, PSECURITY_DESCRIPTOR *PSecurityDescriptor, SIZE_T *PSecurityDescriptorSize)
{
for (;;)
{
NTSTATUS Result = FileSystem->QuerySecurity(FileSystem,
FileName,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
*PSecurityDescriptor, PSecurityDescriptorSize);
if (STATUS_BUFFER_OVERFLOW != Result)
return Result;
MemFree(*PSecurityDescriptor);
*PSecurityDescriptor = MemAlloc(*PSecurityDescriptorSize);
if (0 == *PSecurityDescriptor)
return STATUS_INSUFFICIENT_RESOURCES;
}
}
FSP_API NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, PUINT32 PGrantedAccess)
FSP_FSCTL_TRANSACT_REQ *Request, DWORD DesiredAccess, PDWORD PGrantedAccess)
{
if (0 != FileSystem->AccessCheck)
return FileSystem->AccessCheck(FileSystem, Request, PGrantedAccess);
return FileSystem->AccessCheck(FileSystem, Request, DesiredAccess, PGrantedAccess);
if (0 == FileSystem->QuerySecurity)
{
*PGrantedAccess = DesiredAccess;
return STATUS_SUCCESS;
}
NTSTATUS Result;
PWSTR FileName = (PVOID)Request->Buffer;
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
HANDLE AccessToken = 0;
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
SIZE_T SecurityDescriptorSize;
DWORD PrivilegeSetLength;
BOOLEAN AccessStatus;
s
BOOL AccessStatus;
*PGrantedAccess = 0;
SecurityDescriptor = MemAlloc(1024);
Result = FspOpenAccessToken(FileSystem, Request, &AccessToken);
if (!NT_SUCCESS(Result))
goto exit;
SecurityDescriptorSize = 1024;
SecurityDescriptor = MemAlloc(SecurityDescriptorSize);
if (0 == SecurityDescriptor)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
Result = FspGetSecurityDescriptor();
if (!Request->Req.Create.HasTraversePrivilege)
{
PWSTR Path = (PWSTR)Request->Buffer, Prefix;
DWORD TraverseAccess;
Result = FspOpenAccessToken(FileSystem, Request, &AccessToken);
for (;;)
{
FspPathPrefix(Path, &Prefix, &Path);
if (L'\0' == Path[0])
{
FspPathCombine((PWSTR)Request->Buffer, Path);
break;
}
Prefix = L'\0' == Prefix[0] ? L"\\" : (PWSTR)Request->Buffer;
Result = FspGetFileSecurityDescriptor(FileSystem, Prefix,
&SecurityDescriptor, &SecurityDescriptorSize);
FspPathCombine((PWSTR)Request->Buffer, Path);
if (!NT_SUCCESS(Result))
goto exit;
if (AccessCheck(SecurityDescriptor, AccessToken, FILE_TRAVERSE,
&FspFileGenericMapping, 0, &PrivilegeSetLength, &TraverseAccess, &AccessStatus))
Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
else
Result = FspNtStatusFromWin32(GetLastError());
if (!NT_SUCCESS(Result))
goto exit;
}
}
Result = FspGetFileSecurityDescriptor(FileSystem, (PWSTR)Request->Buffer,
&SecurityDescriptor, &SecurityDescriptorSize);
if (!NT_SUCCESS(Result))
goto exit;
if (AccessCheck(&SecurityDescriptor, AccessToken, Request->Req.Create.DesiredAccess,
if (AccessCheck(SecurityDescriptor, AccessToken, DesiredAccess,
&FspFileGenericMapping, 0, &PrivilegeSetLength, PGrantedAccess, &AccessStatus))
Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
else
Result = FspNtStatusFromWin32(GetLastError());
exit:
MemFree(SecurityDescriptor);
if (0 != AccessToken)
CloseHandle(AccessToken);
MemFree(SecurityDescriptor);
return Result;
}
#endif