diff --git a/build/VStudio/winfsp_dll.vcxproj b/build/VStudio/winfsp_dll.vcxproj index 1111e220..b82dad36 100644 --- a/build/VStudio/winfsp_dll.vcxproj +++ b/build/VStudio/winfsp_dll.vcxproj @@ -24,18 +24,14 @@ - - - + - + - - diff --git a/build/VStudio/winfsp_dll.vcxproj.filters b/build/VStudio/winfsp_dll.vcxproj.filters index 2c9fd85c..1cc5a36a 100644 --- a/build/VStudio/winfsp_dll.vcxproj.filters +++ b/build/VStudio/winfsp_dll.vcxproj.filters @@ -37,28 +37,16 @@ Source - - Source - Source - - Source - - - Source - - - Source - - - Source - Source - + + Source + + Source diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index 7dfe852f..9920e37a 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -166,18 +166,6 @@ VOID FspFileSystemSetDispatcherResult(FSP_FILE_SYSTEM *FileSystem, /* * File System Operations */ -FSP_API PGENERIC_MAPPING FspGetFileGenericMapping(VOID); -FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, - BOOLEAN CheckParentDirectory, BOOLEAN AllowTraverseCheck, - UINT32 DesiredAccess, PUINT32 PGrantedAccess, - PSECURITY_DESCRIPTOR *PSecurityDescriptor); -FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, - PSECURITY_DESCRIPTOR ParentDescriptor, - PSECURITY_DESCRIPTOR *PSecurityDescriptor); -FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, - NTSTATUS (*CreateFunc)()); FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem, @@ -198,6 +186,22 @@ FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); + +/* + * Access + */ +FSP_API PGENERIC_MAPPING FspGetFileGenericMapping(VOID); +FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, + BOOLEAN CheckParentDirectory, BOOLEAN AllowTraverseCheck, + UINT32 DesiredAccess, PUINT32 PGrantedAccess, + PSECURITY_DESCRIPTOR *PSecurityDescriptor); +FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, + PSECURITY_DESCRIPTOR ParentDescriptor, + PSECURITY_DESCRIPTOR *PSecurityDescriptor); +FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, + NTSTATUS (*CreateFunc)()); static inline NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request, diff --git a/src/dll/access.c b/src/dll/access.c new file mode 100644 index 00000000..a2b73537 --- /dev/null +++ b/src/dll/access.c @@ -0,0 +1,234 @@ +/** + * @file dll/access.c + * + * @copyright 2015 Bill Zissimopoulos + */ + +#include + +static GENERIC_MAPPING FspFileGenericMapping = +{ + .GenericRead = FILE_GENERIC_READ, + .GenericWrite = FILE_GENERIC_WRITE, + .GenericExecute = FILE_GENERIC_EXECUTE, + .GenericAll = FILE_ALL_ACCESS, +}; + +FSP_API PGENERIC_MAPPING FspGetFileGenericMapping(VOID) +{ + return &FspFileGenericMapping; +} + +static NTSTATUS FspGetSecurityByName(FSP_FILE_SYSTEM *FileSystem, + PWSTR FileName, PUINT32 PFileAttributes, + PSECURITY_DESCRIPTOR *PSecurityDescriptor, SIZE_T *PSecurityDescriptorSize) +{ + for (;;) + { + NTSTATUS Result = FileSystem->Interface->GetSecurityByName(FileSystem, + FileName, PFileAttributes, *PSecurityDescriptor, PSecurityDescriptorSize); + if (STATUS_BUFFER_OVERFLOW != Result) + return Result; + + MemFree(*PSecurityDescriptor); + *PSecurityDescriptor = MemAlloc(*PSecurityDescriptorSize); + if (0 == *PSecurityDescriptor) + return STATUS_INSUFFICIENT_RESOURCES; + } +} + +FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, + BOOLEAN CheckParentDirectory, BOOLEAN AllowTraverseCheck, + UINT32 DesiredAccess, PUINT32 PGrantedAccess, + PSECURITY_DESCRIPTOR *PSecurityDescriptor) +{ + *PGrantedAccess = 0; + if (0 != PSecurityDescriptor) + *PSecurityDescriptor = 0; + + if (0 == FileSystem->Interface->GetSecurityByName || + (!Request->Req.Create.UserMode && 0 == PSecurityDescriptor)) + { + *PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ? + FspFileGenericMapping.GenericAll : DesiredAccess; + return STATUS_SUCCESS; + } + + NTSTATUS Result; + WCHAR Root[2] = L"\\", TraverseCheckRoot[2] = L"\\"; + PWSTR FileName, Suffix, Prefix, Remain; + UINT32 FileAttributes; + PSECURITY_DESCRIPTOR SecurityDescriptor = 0; + SIZE_T SecurityDescriptorSize; + UINT8 PrivilegeSetBuf[sizeof(PRIVILEGE_SET) + 15 * sizeof(LUID_AND_ATTRIBUTES)]; + PPRIVILEGE_SET PrivilegeSet = (PVOID)PrivilegeSetBuf; + DWORD PrivilegeSetLength = sizeof PrivilegeSetBuf; + UINT32 TraverseAccess; + BOOL AccessStatus; + + if (CheckParentDirectory) + FspPathSuffix((PWSTR)Request->Buffer, &FileName, &Suffix, Root); + else + FileName = (PWSTR)Request->Buffer; + + SecurityDescriptorSize = 1024; + SecurityDescriptor = MemAlloc(SecurityDescriptorSize); + if (0 == SecurityDescriptor) + { + Result = STATUS_INSUFFICIENT_RESOURCES; + goto exit; + } + + if (Request->Req.Create.UserMode && + AllowTraverseCheck && !Request->Req.Create.HasTraversePrivilege) + { + Remain = (PWSTR)FileName; + for (;;) + { + FspPathPrefix(Remain, &Prefix, &Remain, TraverseCheckRoot); + if (L'\0' == Remain[0]) + { + FspPathCombine(FileName, Remain); + break; + } + + Result = FspGetSecurityByName(FileSystem, Prefix, 0, + &SecurityDescriptor, &SecurityDescriptorSize); + + FspPathCombine(FileName, Remain); + + if (!NT_SUCCESS(Result)) + { + if (STATUS_OBJECT_NAME_NOT_FOUND == Result) + Result = STATUS_OBJECT_PATH_NOT_FOUND; + goto exit; + } + + if (0 < SecurityDescriptorSize) + { + if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, FILE_TRAVERSE, + &FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, &TraverseAccess, &AccessStatus)) + Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED; + else + Result = FspNtStatusFromWin32(GetLastError()); + if (!NT_SUCCESS(Result)) + goto exit; + } + } + } + + Result = FspGetSecurityByName(FileSystem, FileName, &FileAttributes, + &SecurityDescriptor, &SecurityDescriptorSize); + if (!NT_SUCCESS(Result)) + goto exit; + + if (Request->Req.Create.UserMode) + { + if (0 < SecurityDescriptorSize) + { + if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, DesiredAccess, + &FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, PGrantedAccess, &AccessStatus)) + Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED; + else + Result = FspNtStatusFromWin32(GetLastError()); + if (!NT_SUCCESS(Result)) + goto exit; + } + + if (CheckParentDirectory) + { + if (0 == (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + Result = STATUS_NOT_A_DIRECTORY; + goto exit; + } + } + else + { + if ((Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE) && + 0 == (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + Result = STATUS_NOT_A_DIRECTORY; + goto exit; + } + if ((Request->Req.Create.CreateOptions & FILE_NON_DIRECTORY_FILE) && + 0 != (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + Result = STATUS_FILE_IS_A_DIRECTORY; + goto exit; + } + } + + if (0 != (FileAttributes & FILE_ATTRIBUTE_READONLY)) + { + if (DesiredAccess & + (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_ADD_SUBDIRECTORY | FILE_DELETE_CHILD)) + { + Result = STATUS_ACCESS_DENIED; + goto exit; + } + if (Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE) + { + Result = STATUS_CANNOT_DELETE; + goto exit; + } + } + + if (0 == SecurityDescriptorSize) + *PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ? + FspFileGenericMapping.GenericAll : DesiredAccess; + } + else + *PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ? + FspFileGenericMapping.GenericAll : DesiredAccess; + + Result = STATUS_SUCCESS; + +exit: + if (0 != PSecurityDescriptor && 0 < SecurityDescriptorSize && NT_SUCCESS(Result)) + *PSecurityDescriptor = SecurityDescriptor; + else + MemFree(SecurityDescriptor); + + if (CheckParentDirectory) + { + FspPathCombine((PWSTR)Request->Buffer, Suffix); + + if (STATUS_OBJECT_NAME_NOT_FOUND == Result) + Result = STATUS_OBJECT_PATH_NOT_FOUND; + } + + return Result; +} + +FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, + PSECURITY_DESCRIPTOR ParentDescriptor, + PSECURITY_DESCRIPTOR *PSecurityDescriptor) +{ + *PSecurityDescriptor = 0; + + if (!CreatePrivateObjectSecurity( + ParentDescriptor, + 0 != Request->Req.Create.SecurityDescriptor.Offset ? + (PSECURITY_DESCRIPTOR)(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset) : 0, + PSecurityDescriptor, + 0 != (Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE), + (HANDLE)Request->Req.Create.AccessToken, + &FspFileGenericMapping)) + return FspNtStatusFromWin32(GetLastError()); + + //DEBUGLOGSD("SDDL=%s", *PSecurityDescriptor); + + return STATUS_SUCCESS; +} + +FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, + NTSTATUS(*CreateFunc)()) +{ + if ((NTSTATUS (*)())FspAccessCheckEx == CreateFunc) + MemFree(SecurityDescriptor); + else if ((NTSTATUS (*)())FspAssignSecurity == CreateFunc) + DestroyPrivateObjectSecurity(&SecurityDescriptor); +} diff --git a/src/dll/cleanup.c b/src/dll/cleanup.c deleted file mode 100644 index c6d1a942..00000000 --- a/src/dll/cleanup.c +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @file dll/cleanup.c - * - * @copyright 2015 Bill Zissimopoulos - */ - -#include - -FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) -{ - if (0 != FileSystem->Interface->Cleanup) - FileSystem->Interface->Cleanup(FileSystem, Request, - (PVOID)Request->Req.Cleanup.UserContext, - 0 != Request->FileName.Size ? (PWSTR)Request->Buffer : 0, - 0 != Request->Req.Cleanup.Delete); - - return STATUS_SUCCESS; -} diff --git a/src/dll/close.c b/src/dll/close.c deleted file mode 100644 index 6a4cb243..00000000 --- a/src/dll/close.c +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @file dll/close.c - * - * @copyright 2015 Bill Zissimopoulos - */ - -#include - -FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) -{ - if (0 != FileSystem->Interface->Close) - FileSystem->Interface->Close(FileSystem, Request, - (PVOID)Request->Req.Close.UserContext); - - return STATUS_SUCCESS; -} diff --git a/src/dll/fileinfo.c b/src/dll/fileinfo.c deleted file mode 100644 index 16c7c298..00000000 --- a/src/dll/fileinfo.c +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file dll/fileinfo.c - * - * @copyright 2015 Bill Zissimopoulos - */ - -#include - -FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) -{ - NTSTATUS Result; - FSP_FSCTL_FILE_INFO FileInfo; - - if (0 == FileSystem->Interface->GetFileInfo) - return STATUS_INVALID_DEVICE_REQUEST; - - memset(&FileInfo, 0, sizeof FileInfo); - Result = FileSystem->Interface->GetFileInfo(FileSystem, Request, - (PVOID)Request->Req.QueryInformation.UserContext, &FileInfo); - if (!NT_SUCCESS(Result)) - return Result; - - memcpy(&Response->Rsp.QueryInformation.FileInfo, &FileInfo, sizeof FileInfo); - return STATUS_SUCCESS; -} - -FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) -{ - NTSTATUS Result; - FSP_FSCTL_FILE_INFO FileInfo; - - Result = STATUS_INVALID_DEVICE_REQUEST; - memset(&FileInfo, 0, sizeof FileInfo); - switch (Request->Req.SetInformation.FileInformationClass) - { - case 4/*FileBasicInformation*/: - if (0 != FileSystem->Interface->SetBasicInfo) - Result = FileSystem->Interface->SetBasicInfo(FileSystem, Request, - (PVOID)Request->Req.SetInformation.UserContext, - Request->Req.SetInformation.Info.Basic.FileAttributes, - Request->Req.SetInformation.Info.Basic.CreationTime, - Request->Req.SetInformation.Info.Basic.LastAccessTime, - Request->Req.SetInformation.Info.Basic.LastWriteTime, - &FileInfo); - break; - case 19/*FileAllocationInformation*/: - if (0 != FileSystem->Interface->SetAllocationSize) - Result = FileSystem->Interface->SetAllocationSize(FileSystem, Request, - (PVOID)Request->Req.SetInformation.UserContext, - Request->Req.SetInformation.Info.Allocation.AllocationSize, - &FileInfo); - else - if (0 != FileSystem->Interface->GetFileInfo && - 0 != FileSystem->Interface->SetFileSize) - { - Result = FileSystem->Interface->GetFileInfo(FileSystem, Request, - (PVOID)Request->Req.SetInformation.UserContext, &FileInfo); - if (NT_SUCCESS(Result) && - Request->Req.SetInformation.Info.Allocation.AllocationSize < FileInfo.FileSize) - { - Result = FileSystem->Interface->SetFileSize(FileSystem, Request, - (PVOID)Request->Req.SetInformation.UserContext, - Request->Req.SetInformation.Info.Allocation.AllocationSize, - FALSE, - &FileInfo); - } - } - break; - case 20/*FileEndOfFileInformation*/: - if (0 != FileSystem->Interface->SetFileSize) - Result = FileSystem->Interface->SetFileSize(FileSystem, Request, - (PVOID)Request->Req.SetInformation.UserContext, - Request->Req.SetInformation.Info.EndOfFile.FileSize, - Request->Req.SetInformation.Info.EndOfFile.AdvanceOnly, - &FileInfo); - break; - case 13/*FileDispositionInformation*/: - if (0 != FileSystem->Interface->CanDelete) - if (Request->Req.SetInformation.Info.Disposition.Delete) - Result = FileSystem->Interface->CanDelete(FileSystem, Request, - (PVOID)Request->Req.SetInformation.UserContext, - (PWSTR)Request->Buffer); - else - Result = STATUS_SUCCESS; - break; - case 10/*FileRenameInformation*/: - if (0 != FileSystem->Interface->Rename) - Result = FileSystem->Interface->Rename(FileSystem, Request, - (PVOID)Request->Req.SetInformation.UserContext, - (PWSTR)Request->Buffer, - (PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset), - Request->Req.SetInformation.Info.Rename.ReplaceIfExists); - break; - } - - if (!NT_SUCCESS(Result)) - return Result; - - memcpy(&Response->Rsp.SetInformation.FileInfo, &FileInfo, sizeof FileInfo); - return STATUS_SUCCESS; -} diff --git a/src/dll/create.c b/src/dll/fsop.c similarity index 65% rename from src/dll/create.c rename to src/dll/fsop.c index d1e4f0c4..303e29e2 100644 --- a/src/dll/create.c +++ b/src/dll/fsop.c @@ -1,238 +1,11 @@ /** - * @file dll/create.c + * @file dll/fsop.c * * @copyright 2015 Bill Zissimopoulos */ #include -static GENERIC_MAPPING FspFileGenericMapping = -{ - .GenericRead = FILE_GENERIC_READ, - .GenericWrite = FILE_GENERIC_WRITE, - .GenericExecute = FILE_GENERIC_EXECUTE, - .GenericAll = FILE_ALL_ACCESS, -}; - -FSP_API PGENERIC_MAPPING FspGetFileGenericMapping(VOID) -{ - return &FspFileGenericMapping; -} - -static NTSTATUS FspGetSecurityByName(FSP_FILE_SYSTEM *FileSystem, - PWSTR FileName, PUINT32 PFileAttributes, - PSECURITY_DESCRIPTOR *PSecurityDescriptor, SIZE_T *PSecurityDescriptorSize) -{ - for (;;) - { - NTSTATUS Result = FileSystem->Interface->GetSecurityByName(FileSystem, - FileName, PFileAttributes, *PSecurityDescriptor, PSecurityDescriptorSize); - if (STATUS_BUFFER_OVERFLOW != Result) - return Result; - - MemFree(*PSecurityDescriptor); - *PSecurityDescriptor = MemAlloc(*PSecurityDescriptorSize); - if (0 == *PSecurityDescriptor) - return STATUS_INSUFFICIENT_RESOURCES; - } -} - -FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, - BOOLEAN CheckParentDirectory, BOOLEAN AllowTraverseCheck, - UINT32 DesiredAccess, PUINT32 PGrantedAccess, - PSECURITY_DESCRIPTOR *PSecurityDescriptor) -{ - *PGrantedAccess = 0; - if (0 != PSecurityDescriptor) - *PSecurityDescriptor = 0; - - if (0 == FileSystem->Interface->GetSecurityByName || - (!Request->Req.Create.UserMode && 0 == PSecurityDescriptor)) - { - *PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ? - FspFileGenericMapping.GenericAll : DesiredAccess; - return STATUS_SUCCESS; - } - - NTSTATUS Result; - WCHAR Root[2] = L"\\", TraverseCheckRoot[2] = L"\\"; - PWSTR FileName, Suffix, Prefix, Remain; - UINT32 FileAttributes; - PSECURITY_DESCRIPTOR SecurityDescriptor = 0; - SIZE_T SecurityDescriptorSize; - UINT8 PrivilegeSetBuf[sizeof(PRIVILEGE_SET) + 15 * sizeof(LUID_AND_ATTRIBUTES)]; - PPRIVILEGE_SET PrivilegeSet = (PVOID)PrivilegeSetBuf; - DWORD PrivilegeSetLength = sizeof PrivilegeSetBuf; - UINT32 TraverseAccess; - BOOL AccessStatus; - - if (CheckParentDirectory) - FspPathSuffix((PWSTR)Request->Buffer, &FileName, &Suffix, Root); - else - FileName = (PWSTR)Request->Buffer; - - SecurityDescriptorSize = 1024; - SecurityDescriptor = MemAlloc(SecurityDescriptorSize); - if (0 == SecurityDescriptor) - { - Result = STATUS_INSUFFICIENT_RESOURCES; - goto exit; - } - - if (Request->Req.Create.UserMode && - AllowTraverseCheck && !Request->Req.Create.HasTraversePrivilege) - { - Remain = (PWSTR)FileName; - for (;;) - { - FspPathPrefix(Remain, &Prefix, &Remain, TraverseCheckRoot); - if (L'\0' == Remain[0]) - { - FspPathCombine(FileName, Remain); - break; - } - - Result = FspGetSecurityByName(FileSystem, Prefix, 0, - &SecurityDescriptor, &SecurityDescriptorSize); - - FspPathCombine(FileName, Remain); - - if (!NT_SUCCESS(Result)) - { - if (STATUS_OBJECT_NAME_NOT_FOUND == Result) - Result = STATUS_OBJECT_PATH_NOT_FOUND; - goto exit; - } - - if (0 < SecurityDescriptorSize) - { - if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, FILE_TRAVERSE, - &FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, &TraverseAccess, &AccessStatus)) - Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED; - else - Result = FspNtStatusFromWin32(GetLastError()); - if (!NT_SUCCESS(Result)) - goto exit; - } - } - } - - Result = FspGetSecurityByName(FileSystem, FileName, &FileAttributes, - &SecurityDescriptor, &SecurityDescriptorSize); - if (!NT_SUCCESS(Result)) - goto exit; - - if (Request->Req.Create.UserMode) - { - if (0 < SecurityDescriptorSize) - { - if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, DesiredAccess, - &FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, PGrantedAccess, &AccessStatus)) - Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED; - else - Result = FspNtStatusFromWin32(GetLastError()); - if (!NT_SUCCESS(Result)) - goto exit; - } - - if (CheckParentDirectory) - { - if (0 == (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - Result = STATUS_NOT_A_DIRECTORY; - goto exit; - } - } - else - { - if ((Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE) && - 0 == (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - Result = STATUS_NOT_A_DIRECTORY; - goto exit; - } - if ((Request->Req.Create.CreateOptions & FILE_NON_DIRECTORY_FILE) && - 0 != (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - Result = STATUS_FILE_IS_A_DIRECTORY; - goto exit; - } - } - - if (0 != (FileAttributes & FILE_ATTRIBUTE_READONLY)) - { - if (DesiredAccess & - (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_ADD_SUBDIRECTORY | FILE_DELETE_CHILD)) - { - Result = STATUS_ACCESS_DENIED; - goto exit; - } - if (Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE) - { - Result = STATUS_CANNOT_DELETE; - goto exit; - } - } - - if (0 == SecurityDescriptorSize) - *PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ? - FspFileGenericMapping.GenericAll : DesiredAccess; - } - else - *PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ? - FspFileGenericMapping.GenericAll : DesiredAccess; - - Result = STATUS_SUCCESS; - -exit: - if (0 != PSecurityDescriptor && 0 < SecurityDescriptorSize && NT_SUCCESS(Result)) - *PSecurityDescriptor = SecurityDescriptor; - else - MemFree(SecurityDescriptor); - - if (CheckParentDirectory) - { - FspPathCombine((PWSTR)Request->Buffer, Suffix); - - if (STATUS_OBJECT_NAME_NOT_FOUND == Result) - Result = STATUS_OBJECT_PATH_NOT_FOUND; - } - - return Result; -} - -FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, - PSECURITY_DESCRIPTOR ParentDescriptor, - PSECURITY_DESCRIPTOR *PSecurityDescriptor) -{ - *PSecurityDescriptor = 0; - - if (!CreatePrivateObjectSecurity( - ParentDescriptor, - 0 != Request->Req.Create.SecurityDescriptor.Offset ? - (PSECURITY_DESCRIPTOR)(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset) : 0, - PSecurityDescriptor, - 0 != (Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE), - (HANDLE)Request->Req.Create.AccessToken, - &FspFileGenericMapping)) - return FspNtStatusFromWin32(GetLastError()); - - //DEBUGLOGSD("SDDL=%s", *PSecurityDescriptor); - - return STATUS_SUCCESS; -} - -FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, - NTSTATUS(*CreateFunc)()) -{ - if ((NTSTATUS (*)())FspAccessCheckEx == CreateFunc) - MemFree(SecurityDescriptor); - else if ((NTSTATUS (*)())FspAssignSecurity == CreateFunc) - DestroyPrivateObjectSecurity(&SecurityDescriptor); -} - static inline NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request, @@ -248,7 +21,7 @@ NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem, if (NT_SUCCESS(Result)) { *PGrantedAccess = (MAXIMUM_ALLOWED & Request->Req.Create.DesiredAccess) ? - FspFileGenericMapping.GenericAll : Request->Req.Create.DesiredAccess; + FspGetFileGenericMapping()->GenericAll : Request->Req.Create.DesiredAccess; } return Result; @@ -606,3 +379,187 @@ FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem, memcpy(&Response->Rsp.Overwrite.FileInfo, &FileInfo, sizeof FileInfo); return STATUS_SUCCESS; } + +FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) +{ + if (0 != FileSystem->Interface->Cleanup) + FileSystem->Interface->Cleanup(FileSystem, Request, + (PVOID)Request->Req.Cleanup.UserContext, + 0 != Request->FileName.Size ? (PWSTR)Request->Buffer : 0, + 0 != Request->Req.Cleanup.Delete); + + return STATUS_SUCCESS; +} + +FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) +{ + if (0 != FileSystem->Interface->Close) + FileSystem->Interface->Close(FileSystem, Request, + (PVOID)Request->Req.Close.UserContext); + + return STATUS_SUCCESS; +} + +FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) +{ + NTSTATUS Result; + FSP_FSCTL_FILE_INFO FileInfo; + + if (0 == FileSystem->Interface->GetFileInfo) + return STATUS_INVALID_DEVICE_REQUEST; + + memset(&FileInfo, 0, sizeof FileInfo); + Result = FileSystem->Interface->GetFileInfo(FileSystem, Request, + (PVOID)Request->Req.QueryInformation.UserContext, &FileInfo); + if (!NT_SUCCESS(Result)) + return Result; + + memcpy(&Response->Rsp.QueryInformation.FileInfo, &FileInfo, sizeof FileInfo); + return STATUS_SUCCESS; +} + +FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) +{ + NTSTATUS Result; + FSP_FSCTL_FILE_INFO FileInfo; + + Result = STATUS_INVALID_DEVICE_REQUEST; + memset(&FileInfo, 0, sizeof FileInfo); + switch (Request->Req.SetInformation.FileInformationClass) + { + case 4/*FileBasicInformation*/: + if (0 != FileSystem->Interface->SetBasicInfo) + Result = FileSystem->Interface->SetBasicInfo(FileSystem, Request, + (PVOID)Request->Req.SetInformation.UserContext, + Request->Req.SetInformation.Info.Basic.FileAttributes, + Request->Req.SetInformation.Info.Basic.CreationTime, + Request->Req.SetInformation.Info.Basic.LastAccessTime, + Request->Req.SetInformation.Info.Basic.LastWriteTime, + &FileInfo); + break; + case 19/*FileAllocationInformation*/: + if (0 != FileSystem->Interface->SetAllocationSize) + Result = FileSystem->Interface->SetAllocationSize(FileSystem, Request, + (PVOID)Request->Req.SetInformation.UserContext, + Request->Req.SetInformation.Info.Allocation.AllocationSize, + &FileInfo); + else + if (0 != FileSystem->Interface->GetFileInfo && + 0 != FileSystem->Interface->SetFileSize) + { + Result = FileSystem->Interface->GetFileInfo(FileSystem, Request, + (PVOID)Request->Req.SetInformation.UserContext, &FileInfo); + if (NT_SUCCESS(Result) && + Request->Req.SetInformation.Info.Allocation.AllocationSize < FileInfo.FileSize) + { + Result = FileSystem->Interface->SetFileSize(FileSystem, Request, + (PVOID)Request->Req.SetInformation.UserContext, + Request->Req.SetInformation.Info.Allocation.AllocationSize, + FALSE, + &FileInfo); + } + } + break; + case 20/*FileEndOfFileInformation*/: + if (0 != FileSystem->Interface->SetFileSize) + Result = FileSystem->Interface->SetFileSize(FileSystem, Request, + (PVOID)Request->Req.SetInformation.UserContext, + Request->Req.SetInformation.Info.EndOfFile.FileSize, + Request->Req.SetInformation.Info.EndOfFile.AdvanceOnly, + &FileInfo); + break; + case 13/*FileDispositionInformation*/: + if (0 != FileSystem->Interface->CanDelete) + if (Request->Req.SetInformation.Info.Disposition.Delete) + Result = FileSystem->Interface->CanDelete(FileSystem, Request, + (PVOID)Request->Req.SetInformation.UserContext, + (PWSTR)Request->Buffer); + else + Result = STATUS_SUCCESS; + break; + case 10/*FileRenameInformation*/: + if (0 != FileSystem->Interface->Rename) + Result = FileSystem->Interface->Rename(FileSystem, Request, + (PVOID)Request->Req.SetInformation.UserContext, + (PWSTR)Request->Buffer, + (PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset), + Request->Req.SetInformation.Info.Rename.ReplaceIfExists); + break; + } + + if (!NT_SUCCESS(Result)) + return Result; + + memcpy(&Response->Rsp.SetInformation.FileInfo, &FileInfo, sizeof FileInfo); + return STATUS_SUCCESS; +} + +FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) +{ + NTSTATUS Result; + FSP_FSCTL_VOLUME_INFO VolumeInfo; + + if (0 == FileSystem->Interface->GetVolumeInfo) + return STATUS_INVALID_DEVICE_REQUEST; + + memset(&VolumeInfo, 0, sizeof VolumeInfo); + Result = FileSystem->Interface->GetVolumeInfo(FileSystem, Request, &VolumeInfo); + if (!NT_SUCCESS(Result)) + return Result; + + memcpy(&Response->Rsp.QueryVolumeInformation.VolumeInfo, &VolumeInfo, sizeof VolumeInfo); + return STATUS_SUCCESS; +} + +FSP_API NTSTATUS FspFileSystemOpSetVolumeInformation(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) +{ + NTSTATUS Result; + FSP_FSCTL_VOLUME_INFO VolumeInfo; + + Result = STATUS_INVALID_DEVICE_REQUEST; + memset(&VolumeInfo, 0, sizeof VolumeInfo); + switch (Request->Req.SetVolumeInformation.FsInformationClass) + { + case 2/*FileFsLabelInformation*/: + if (0 != FileSystem->Interface->SetVolumeLabel) + Result = FileSystem->Interface->SetVolumeLabel(FileSystem, Request, + (PWSTR)Request->Buffer, + &VolumeInfo); + } + + if (!NT_SUCCESS(Result)) + return Result; + + memcpy(&Response->Rsp.SetVolumeInformation.VolumeInfo, &VolumeInfo, sizeof VolumeInfo); + return STATUS_SUCCESS; +} + +FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) +{ + NTSTATUS Result; + + if (0 == FileSystem->Interface->GetSecurity) + return STATUS_INVALID_DEVICE_REQUEST; + + (VOID)Result; + return STATUS_INVALID_DEVICE_REQUEST; +} + +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; +} diff --git a/src/dll/security.c b/src/dll/security.c deleted file mode 100644 index 7d2288ec..00000000 --- a/src/dll/security.c +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file dll/security.c - * - * @copyright 2015 Bill Zissimopoulos - */ - -#include - -FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) -{ - NTSTATUS Result; - - if (0 == FileSystem->Interface->GetSecurity) - return STATUS_INVALID_DEVICE_REQUEST; - - (VOID)Result; - return STATUS_INVALID_DEVICE_REQUEST; -} - -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; -} diff --git a/src/dll/volinfo.c b/src/dll/volinfo.c deleted file mode 100644 index 12b2ccc8..00000000 --- a/src/dll/volinfo.c +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @file dll/volinfo.c - * - * @copyright 2015 Bill Zissimopoulos - */ - -#include - -FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) -{ - NTSTATUS Result; - FSP_FSCTL_VOLUME_INFO VolumeInfo; - - if (0 == FileSystem->Interface->GetVolumeInfo) - return STATUS_INVALID_DEVICE_REQUEST; - - memset(&VolumeInfo, 0, sizeof VolumeInfo); - Result = FileSystem->Interface->GetVolumeInfo(FileSystem, Request, &VolumeInfo); - if (!NT_SUCCESS(Result)) - return Result; - - memcpy(&Response->Rsp.QueryVolumeInformation.VolumeInfo, &VolumeInfo, sizeof VolumeInfo); - return STATUS_SUCCESS; -} - -FSP_API NTSTATUS FspFileSystemOpSetVolumeInformation(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) -{ - NTSTATUS Result; - FSP_FSCTL_VOLUME_INFO VolumeInfo; - - Result = STATUS_INVALID_DEVICE_REQUEST; - memset(&VolumeInfo, 0, sizeof VolumeInfo); - switch (Request->Req.SetVolumeInformation.FsInformationClass) - { - case 2/*FileFsLabelInformation*/: - if (0 != FileSystem->Interface->SetVolumeLabel) - Result = FileSystem->Interface->SetVolumeLabel(FileSystem, Request, - (PWSTR)Request->Buffer, - &VolumeInfo); - } - - if (!NT_SUCCESS(Result)) - return Result; - - memcpy(&Response->Rsp.SetVolumeInformation.VolumeInfo, &VolumeInfo, sizeof VolumeInfo); - return STATUS_SUCCESS; -}