diff --git a/src/sys/create.c b/src/sys/create.c index 03a5a1c8..00e205d9 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -124,8 +124,6 @@ static NTSTATUS FspFsvolCreate( FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode; BOOLEAN HasTraversePrivilege = BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE); - BOOLEAN IsAbsoluteSecurityDescriptor = FALSE; - BOOLEAN IsSelfRelativeSecurityDescriptor = FALSE; BOOLEAN HasTrailingBackslash = FALSE; FSP_FILE_NODE *FileNode, *RelatedFileNode; FSP_FILE_DESC *FileDesc; @@ -144,27 +142,16 @@ static NTSTATUS FspFsvolCreate( return STATUS_ACCESS_DENIED; /* check create options */ - if (FlagOn(CreateOptions, FILE_NON_DIRECTORY_FILE) && FlagOn(CreateOptions, FILE_DIRECTORY_FILE)) + if (FlagOn(CreateOptions, FILE_NON_DIRECTORY_FILE) && + FlagOn(CreateOptions, FILE_DIRECTORY_FILE)) return STATUS_INVALID_PARAMETER; /* check security descriptor validity */ if (0 != SecurityDescriptor) { - IsAbsoluteSecurityDescriptor = RtlValidSecurityDescriptor(SecurityDescriptor); - if (IsAbsoluteSecurityDescriptor) - { - Result = RtlAbsoluteToSelfRelativeSD(SecurityDescriptor, 0, &SecurityDescriptorSize); - if (STATUS_BUFFER_TOO_SMALL != Result) - return STATUS_INVALID_PARAMETER; - } - else - { - SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor); - IsSelfRelativeSecurityDescriptor = RtlValidRelativeSecurityDescriptor( - SecurityDescriptor, SecurityDescriptorSize, 0); - if (!IsSelfRelativeSecurityDescriptor) - return STATUS_INVALID_PARAMETER; - } + if (!RtlValidSecurityDescriptor(SecurityDescriptor)) + return STATUS_INVALID_PARAMETER; + SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor); } /* according to fastfat, filenames that begin with two backslashes are ok */ @@ -323,19 +310,8 @@ static NTSTATUS FspFsvolCreate( Request->Req.Create.OpenTargetDirectory = BooleanFlagOn(Flags, SL_OPEN_TARGET_DIRECTORY); Request->Req.Create.CaseSensitive = BooleanFlagOn(Flags, SL_CASE_SENSITIVE); - /* copy the security descriptor into the request */ - if (IsAbsoluteSecurityDescriptor) - { - Result = RtlAbsoluteToSelfRelativeSD(SecurityDescriptor, - Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, &SecurityDescriptorSize); - if (!NT_SUCCESS(Result)) - { - if (STATUS_BAD_DESCRIPTOR_FORMAT == Result || STATUS_BUFFER_TOO_SMALL == Result) - Result = STATUS_INVALID_PARAMETER; /* should not happen */ - return Result; - } - } - else if (IsSelfRelativeSecurityDescriptor) + /* copy the security descriptor (if any) into the request */ + if (0 != SecurityDescriptorSize) RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, SecurityDescriptor, SecurityDescriptorSize); diff --git a/tst/winfsp-tests/create-test.c b/tst/winfsp-tests/create-test.c index 68816964..7644dc8c 100644 --- a/tst/winfsp-tests/create-test.c +++ b/tst/winfsp-tests/create-test.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "memfs.h" @@ -110,7 +111,64 @@ void create_test(void) create_dotest(MemfsNet, L"\\\\memfs\\share"); } +void create_sd_dotest(ULONG Flags, PWSTR Prefix) +{ + void *memfs = memfs_start(Flags); + + static PWSTR Sddl = L"D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;WD)"; + PSECURITY_DESCRIPTOR SecurityDescriptor; + SECURITY_ATTRIBUTES SecurityAttributes = { 0 }; + HANDLE Handle; + BOOLEAN Success; + WCHAR FilePath[MAX_PATH]; + + Success = ConvertStringSecurityDescriptorToSecurityDescriptorW(Sddl, SDDL_REVISION_1, &SecurityDescriptor, 0); + ASSERT(Success); + + SecurityAttributes.nLength = sizeof SecurityAttributes; + SecurityAttributes.lpSecurityDescriptor = SecurityDescriptor; + + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", + Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); + + Handle = CreateFileW(FilePath, + GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &SecurityAttributes, + CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); + ASSERT(INVALID_HANDLE_VALUE != Handle); + CloseHandle(Handle); + + Handle = CreateFileW(FilePath, + GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); + ASSERT(INVALID_HANDLE_VALUE != Handle); + CloseHandle(Handle); + + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1", + Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); + + Success = CreateDirectory(FilePath, &SecurityAttributes); + ASSERT(Success); + + Handle = CreateFileW(FilePath, + GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_DELETE_ON_CLOSE, 0); + ASSERT(INVALID_HANDLE_VALUE != Handle); + CloseHandle(Handle); + + LocalFree(SecurityDescriptor); + + memfs_stop(memfs); +} + +void create_sd_test(void) +{ + if (WinFspDiskTests) + create_sd_dotest(MemfsDisk, 0); + if (0 && WinFspNetTests) + create_sd_dotest(MemfsNet, L"\\\\memfs\\share"); +} + void create_tests(void) { TEST(create_test); + TEST(create_sd_test); }