Compare commits

...

6 Commits

8 changed files with 75 additions and 25 deletions

View File

@ -18,7 +18,7 @@
<MyCanonicalVersion>1.5</MyCanonicalVersion> <MyCanonicalVersion>1.5</MyCanonicalVersion>
<MyProductVersion>2019.3 B4</MyProductVersion> <MyProductVersion>2019.3 B5</MyProductVersion>
<MyProductStage>Beta</MyProductStage> <MyProductStage>Beta</MyProductStage>
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion> <MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>

View File

@ -207,6 +207,11 @@ static inline int FspKuMultiByteToWideChar(
return ByteCount / sizeof(WCHAR); return ByteCount / sizeof(WCHAR);
} }
static inline PGENERIC_MAPPING FspGetFileGenericMapping(VOID)
{
return IoGetFileObjectGenericMapping();
}
static inline void *MemAlloc(size_t Size) static inline void *MemAlloc(size_t Size)
{ {
return FspAlloc(Size); return FspAlloc(Size);

View File

@ -725,6 +725,20 @@ lasterror:
goto exit; goto exit;
} }
static inline ACCESS_MASK FspPosixCanonicalizeAccessMask(ACCESS_MASK AccessMask)
{
PGENERIC_MAPPING Mapping = FspGetFileGenericMapping();
if (AccessMask & GENERIC_READ)
AccessMask |= Mapping->GenericRead;
if (AccessMask & GENERIC_WRITE)
AccessMask |= Mapping->GenericWrite;
if (AccessMask & GENERIC_EXECUTE)
AccessMask |= Mapping->GenericExecute;
if (AccessMask & GENERIC_ALL)
AccessMask |= Mapping->GenericAll;
return AccessMask & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
}
static inline UINT32 FspPosixMapAccessMaskToPermission(ACCESS_MASK AccessMask) static inline UINT32 FspPosixMapAccessMaskToPermission(ACCESS_MASK AccessMask)
{ {
/* [PERMS] /* [PERMS]
@ -749,6 +763,14 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
{ {
FSP_KU_CODE; FSP_KU_CODE;
BOOLEAN OwnerOptional = (UINT_PTR)PUid & 1;
PUid = (PVOID)((UINT_PTR)PUid & ~1);
UINT32 OrigUid = *PUid;
BOOLEAN GroupOptional = (UINT_PTR)PGid & 1;
PGid = (PVOID)((UINT_PTR)PGid & ~1);
UINT32 OrigGid = *PGid;
PSID OwnerSid = 0, GroupSid = 0; PSID OwnerSid = 0, GroupSid = 0;
BOOL Defaulted, DaclPresent; BOOL Defaulted, DaclPresent;
PACL Acl = 0; PACL Acl = 0;
@ -757,6 +779,7 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
PSID AceSid; PSID AceSid;
DWORD AceAccessMask; DWORD AceAccessMask;
DWORD OwnerAllow, OwnerDeny, GroupAllow, GroupDeny, WorldAllow, WorldDeny; DWORD OwnerAllow, OwnerDeny, GroupAllow, GroupDeny, WorldAllow, WorldDeny;
UINT32 AceUid = 0;
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
NTSTATUS Result; NTSTATUS Result;
@ -771,13 +794,23 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
if (!GetSecurityDescriptorDacl(SecurityDescriptor, &DaclPresent, &Acl, &Defaulted)) if (!GetSecurityDescriptorDacl(SecurityDescriptor, &DaclPresent, &Acl, &Defaulted))
goto lasterror; goto lasterror;
Result = FspPosixMapSidToUid(OwnerSid, &Uid); if (0 == OwnerSid && OwnerOptional)
if (!NT_SUCCESS(Result)) Uid = OrigUid;
goto exit; else
{
Result = FspPosixMapSidToUid(OwnerSid, &Uid);
if (!NT_SUCCESS(Result))
goto exit;
}
Result = FspPosixMapSidToUid(GroupSid, &Gid); if (0 == GroupSid && GroupOptional)
if (!NT_SUCCESS(Result)) Gid = OrigGid;
goto exit; else
{
Result = FspPosixMapSidToUid(GroupSid, &Gid);
if (!NT_SUCCESS(Result))
goto exit;
}
if (0 != Acl) if (0 != Acl)
{ {
@ -810,6 +843,8 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
else else
continue; continue;
AceAccessMask = FspPosixCanonicalizeAccessMask(AceAccessMask);
/* [PERMS] /* [PERMS]
* If the ACE contains the Authenticated Users SID or the World SID then * If the ACE contains the Authenticated Users SID or the World SID then
* add the allowed or denied access right bits into the "owner", "group" * add the allowed or denied access right bits into the "owner", "group"
@ -840,6 +875,9 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
} }
else else
{ {
if (0 == OwnerSid || 0 == GroupSid)
FspPosixMapSidToUid(AceSid, &AceUid);
/* [PERMS] /* [PERMS]
* Note that if the file owner and file group SIDs are the same, * Note that if the file owner and file group SIDs are the same,
* then the access rights are saved in both the "owner" and "group" * then the access rights are saved in both the "owner" and "group"
@ -851,7 +889,7 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
* in the "group" collection as appropriate in the corresponding set of * in the "group" collection as appropriate in the corresponding set of
* granted or denied rights (as described above). * granted or denied rights (as described above).
*/ */
if (EqualSid(GroupSid, AceSid)) if (0 != GroupSid ? EqualSid(GroupSid, AceSid) : (Gid == AceUid))
{ {
if (ACCESS_ALLOWED_ACE_TYPE == Ace->AceType) if (ACCESS_ALLOWED_ACE_TYPE == Ace->AceType)
GroupAllow |= AceAccessMask & ~GroupDeny; GroupAllow |= AceAccessMask & ~GroupDeny;
@ -864,7 +902,7 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
* in the "owner" collection as appropriate in the corresponding set of * in the "owner" collection as appropriate in the corresponding set of
* granted or denied rights (as described above). * granted or denied rights (as described above).
*/ */
if (EqualSid(OwnerSid, AceSid)) if (0 != OwnerSid ? EqualSid(OwnerSid, AceSid) : (Uid == AceUid))
{ {
if (ACCESS_ALLOWED_ACE_TYPE == Ace->AceType) if (ACCESS_ALLOWED_ACE_TYPE == Ace->AceType)
OwnerAllow |= AceAccessMask & ~OwnerDeny; OwnerAllow |= AceAccessMask & ~OwnerDeny;

View File

@ -308,7 +308,7 @@ VOID FspPropagateTopFlags(PIRP Irp, PIRP TopLevelIrp)
{ {
DEBUGBREAK_EX(iorecu); DEBUGBREAK_EX(iorecu);
FspIrpSetTopFlags(Irp, FspIrpFlags(TopLevelIrp)); FspIrpSetTopFlags(Irp, FspIrpTopFlags(TopLevelIrp) | FspIrpFlags(TopLevelIrp));
} }
} }
} }

View File

@ -1337,8 +1337,9 @@ NTSTATUS FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp
!MmFlushImageSection(&DescendantFileNode->NonPaged->SectionObjectPointers, !MmFlushImageSection(&DescendantFileNode->NonPaged->SectionObjectPointers,
MmFlushForDelete))) MmFlushForDelete)))
{ {
/* release the FileNode in case of failure! */ /* release the FileNode and rename lock in case of failure! */
FspFileNodeReleaseF(FileNode, AcquireFlags); FspFileNodeReleaseF(FileNode, AcquireFlags);
FspFsvolDeviceFileRenameRelease(FsvolDeviceObject);
Result = STATUS_ACCESS_DENIED; Result = STATUS_ACCESS_DENIED;
goto exit; goto exit;
@ -1441,8 +1442,9 @@ NTSTATUS FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp
if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result || !NT_SUCCESS(Result)) if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result || !NT_SUCCESS(Result))
{ {
/* release the FileNode so that we can safely wait without deadlocks */ /* release the FileNode and rename lock so that we can safely wait without deadlocks */
FspFileNodeReleaseF(FileNode, AcquireFlags); FspFileNodeReleaseF(FileNode, AcquireFlags);
FspFsvolDeviceFileRenameRelease(FsvolDeviceObject);
/* wait for oplock breaks to finish */ /* wait for oplock breaks to finish */
for ( for (
@ -1488,8 +1490,9 @@ NTSTATUS FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp
if (DescendantFileNode != FileNode && 0 < DescendantFileNode->HandleCount) if (DescendantFileNode != FileNode && 0 < DescendantFileNode->HandleCount)
{ {
/* release the FileNode in case of failure! */ /* release the FileNode and rename lock in case of failure! */
FspFileNodeReleaseF(FileNode, AcquireFlags); FspFileNodeReleaseF(FileNode, AcquireFlags);
FspFsvolDeviceFileRenameRelease(FsvolDeviceObject);
Result = STATUS_ACCESS_DENIED; Result = STATUS_ACCESS_DENIED;
break; break;

View File

@ -1576,8 +1576,8 @@ static NTSTATUS FspFsvolSetRenameInformation(
ASSERT(TargetFileNode->IsDirectory); ASSERT(TargetFileNode->IsDirectory);
} }
FspFsvolDeviceFileRenameAcquireExclusive(FsvolDeviceObject);
retry: retry:
FspFsvolDeviceFileRenameAcquireExclusive(FsvolDeviceObject);
FspFileNodeAcquireExclusive(FileNode, Full); FspFileNodeAcquireExclusive(FileNode, Full);
if (0 == Request) if (0 == Request)
@ -1651,13 +1651,13 @@ retry:
Result = FspFileNodeRenameCheck(FsvolDeviceObject, Irp, Result = FspFileNodeRenameCheck(FsvolDeviceObject, Irp,
FileNode, FspFileNodeAcquireFull, FileNode, FspFileNodeAcquireFull,
&FileNode->FileName, TRUE); &FileNode->FileName, TRUE);
/* FspFileNodeRenameCheck releases FileNode with STATUS_OPLOCK_BREAK_IN_PROGRESS or failure */ /* FspFileNodeRenameCheck releases FileNode and rename lock on failure */
if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result) if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result)
goto retry; goto retry;
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
Result = STATUS_ACCESS_DENIED; Result = STATUS_ACCESS_DENIED;
goto rename_unlock_exit; goto exit;
} }
if (0 != FspFileNameCompare(&FileNode->FileName, &NewFileName, !FileDesc->CaseSensitive, 0)) if (0 != FspFileNameCompare(&FileNode->FileName, &NewFileName, !FileDesc->CaseSensitive, 0))
@ -1665,13 +1665,13 @@ retry:
Result = FspFileNodeRenameCheck(FsvolDeviceObject, Irp, Result = FspFileNodeRenameCheck(FsvolDeviceObject, Irp,
FileNode, FspFileNodeAcquireFull, FileNode, FspFileNodeAcquireFull,
&NewFileName, FALSE); &NewFileName, FALSE);
/* FspFileNodeRenameCheck releases FileNode with STATUS_OPLOCK_BREAK_IN_PROGRESS or failure */ /* FspFileNodeRenameCheck releases FileNode and rename lock on failure */
if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result) if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result)
goto retry; goto retry;
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
Result = STATUS_ACCESS_DENIED; Result = STATUS_ACCESS_DENIED;
goto rename_unlock_exit; goto exit;
} }
} }
else else
@ -1713,9 +1713,9 @@ retry:
unlock_exit: unlock_exit:
FspFileNodeRelease(FileNode, Full); FspFileNodeRelease(FileNode, Full);
rename_unlock_exit:
FspFsvolDeviceFileRenameRelease(FsvolDeviceObject); FspFsvolDeviceFileRenameRelease(FsvolDeviceObject);
exit:
return Result; return Result;
} }

View File

@ -86,6 +86,13 @@ if not %signfail%==0 echo SIGNING FAILED! The product has been successfully buil
for %%f in (build\%Configuration%\winfsp-*.msi) do set Version=%%~nf for %%f in (build\%Configuration%\winfsp-*.msi) do set Version=%%~nf
set Version=!Version:winfsp-=! set Version=!Version:winfsp-=!
if X%SignedPackage%==X (
pushd build\%Configuration%
powershell -command "Compress-Archive -Path winfsp-tests-*.exe,..\..\..\..\License.txt,..\..\..\..\tst\winfsp-tests\README.md -DestinationPath winfsp-tests-!Version!.zip"
if errorlevel 1 goto fail
popd
)
where /q choco.exe where /q choco.exe
if %ERRORLEVEL% equ 0 ( if %ERRORLEVEL% equ 0 (
copy ..\choco\* build\%Configuration% copy ..\choco\* build\%Configuration%
@ -95,11 +102,6 @@ if %ERRORLEVEL% equ 0 (
if errorlevel 1 goto fail if errorlevel 1 goto fail
) )
pushd build\%Configuration%
powershell -command "Compress-Archive -Path winfsp-tests-*.exe,..\..\..\..\License.txt,..\..\..\..\tst\winfsp-tests\README.md -DestinationPath winfsp-tests-!Version!.zip"
if errorlevel 1 goto fail
popd
exit /b 0 exit /b 0
:fail :fail

View File

@ -134,7 +134,9 @@ BOOL WINAPI ResilientRemoveDirectoryW(
else else
{ {
for (ULONG MaxTries = DeleteMaxTries; for (ULONG MaxTries = DeleteMaxTries;
!Success && ERROR_SHARING_VIOLATION == GetLastError() && 0 != MaxTries; !Success &&
(ERROR_SHARING_VIOLATION == GetLastError() || ERROR_DIR_NOT_EMPTY == GetLastError()) &&
0 != MaxTries;
MaxTries--) MaxTries--)
{ {
Sleep(DeleteSleepTimeout); Sleep(DeleteSleepTimeout);