mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 08:53:01 -05:00
dll: POSIX interop: FspPosixMapPermissionsToSecurityDescriptor
This commit is contained in:
parent
0d4aa15377
commit
1432d711d8
154
src/dll/posix.c
154
src/dll/posix.c
@ -5,13 +5,13 @@
|
|||||||
* This file provides routines for Windows/POSIX interoperability. It is based
|
* This file provides routines for Windows/POSIX interoperability. It is based
|
||||||
* on "Services for UNIX" and Cygwin. See the following documents:
|
* on "Services for UNIX" and Cygwin. See the following documents:
|
||||||
*
|
*
|
||||||
* [PERM]
|
* [PERMS]
|
||||||
* https://technet.microsoft.com/en-us/library/bb463216.aspx
|
* https://technet.microsoft.com/en-us/library/bb463216.aspx
|
||||||
* [WKSID]
|
* [WKSID]
|
||||||
* https://support.microsoft.com/en-us/kb/243330
|
* https://support.microsoft.com/en-us/kb/243330
|
||||||
* [IDMAP]
|
* [IDMAP]
|
||||||
* https://cygwin.com/cygwin-ug-net/ntsec.html
|
* https://cygwin.com/cygwin-ug-net/ntsec.html
|
||||||
* [NAME]
|
* [SNAME]
|
||||||
* https://www.cygwin.com/cygwin-ug-net/using-specialnames.html
|
* https://www.cygwin.com/cygwin-ug-net/using-specialnames.html
|
||||||
*
|
*
|
||||||
* @copyright 2015-2016 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
@ -29,6 +29,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dll/library.h>
|
#include <dll/library.h>
|
||||||
|
#include <aclapi.h>
|
||||||
#define _NTDEF_
|
#define _NTDEF_
|
||||||
#include <ntsecapi.h>
|
#include <ntsecapi.h>
|
||||||
|
|
||||||
@ -356,11 +357,158 @@ FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)())
|
|||||||
MemFree(Sid);
|
MemFree(Sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FspPosixDefaultPerm \
|
||||||
|
(SYNCHRONIZE | READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_READ_EA)
|
||||||
|
#define FspPosixOwnerDefaultPerm \
|
||||||
|
(FspPosixDefaultPerm | DELETE | WRITE_DAC | WRITE_OWNER | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA)
|
||||||
|
|
||||||
|
static inline ACCESS_MASK FspPosixMapPermissionToAccessMask(UINT32 Mode, UINT32 Perm)
|
||||||
|
{
|
||||||
|
/* if only directory bit is set out of directory/sticky bit then DeleteChild */
|
||||||
|
ACCESS_MASK DeleteChild = 0040000 == (Mode & 0041000) ? FILE_DELETE_CHILD : 0;
|
||||||
|
|
||||||
|
return
|
||||||
|
((Perm & 4) ? FILE_READ_DATA : 0) |
|
||||||
|
((Perm & 2) ? FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA | FILE_APPEND_DATA | DeleteChild : 0) |
|
||||||
|
((Perm & 1) ? FILE_EXECUTE : 0);
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
|
FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
|
||||||
UINT32 Uid, UINT32 Gid, UINT32 Mode,
|
UINT32 Uid, UINT32 Gid, UINT32 Mode,
|
||||||
PSECURITY_DESCRIPTOR *PSecurityDescriptor)
|
PSECURITY_DESCRIPTOR *PSecurityDescriptor)
|
||||||
{
|
{
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
PSID OwnerSid = 0, GroupSid = 0, WorldSid = 0;
|
||||||
|
UINT32 OwnerPerm, OwnerDeny, GroupPerm, GroupDeny, WorldPerm;
|
||||||
|
PACL Acl = 0;
|
||||||
|
SECURITY_DESCRIPTOR SecurityDescriptor;
|
||||||
|
PSECURITY_DESCRIPTOR RelativeSecurityDescriptor = 0;
|
||||||
|
ULONG Size;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
*PSecurityDescriptor = 0;
|
||||||
|
|
||||||
|
Result = FspPosixMapUidToSid(Uid, OwnerSid);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = FspPosixMapUidToSid(Gid, GroupSid);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = FspPosixMapUidToSid(0x10100, WorldSid);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
OwnerPerm = (Mode & 0700) >> 6;
|
||||||
|
GroupPerm = (Mode & 0070) >> 3;
|
||||||
|
WorldPerm = (Mode & 0007);
|
||||||
|
|
||||||
|
OwnerDeny = (OwnerPerm ^ GroupPerm) & GroupPerm;
|
||||||
|
OwnerDeny |= (OwnerPerm ^ WorldPerm) & WorldPerm;
|
||||||
|
GroupDeny = (GroupPerm ^ WorldPerm) & WorldPerm;
|
||||||
|
|
||||||
|
Size = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) * 3 +
|
||||||
|
sizeof(ACCESS_DENIED_ACE) * (!!OwnerDeny + !!GroupDeny);
|
||||||
|
Size += GetLengthSid(OwnerSid) - sizeof(DWORD);
|
||||||
|
Size += GetLengthSid(GroupSid) - sizeof(DWORD);
|
||||||
|
Size += GetLengthSid(WorldSid) - sizeof(DWORD);
|
||||||
|
if (OwnerDeny)
|
||||||
|
Size += GetLengthSid(OwnerSid) - sizeof(DWORD);
|
||||||
|
if (GroupDeny)
|
||||||
|
Size += GetLengthSid(GroupSid) - sizeof(DWORD);
|
||||||
|
Size += sizeof(DWORD) - 1;
|
||||||
|
Size &= ~sizeof(DWORD);
|
||||||
|
|
||||||
|
Acl = MemAlloc(Size);
|
||||||
|
if (0 == Acl)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!InitializeAcl(Acl, Size, ACL_REVISION))
|
||||||
|
goto lasterror;
|
||||||
|
|
||||||
|
if (!AddAccessAllowedAce(Acl, ACL_REVISION,
|
||||||
|
FspPosixOwnerDefaultPerm | FspPosixMapPermissionToAccessMask(Mode & ~001000, OwnerPerm),
|
||||||
|
OwnerSid))
|
||||||
|
goto lasterror;
|
||||||
|
if (OwnerDeny)
|
||||||
|
{
|
||||||
|
if (!AddAccessDeniedAce(Acl, ACL_REVISION,
|
||||||
|
FspPosixMapPermissionToAccessMask(Mode & ~001000, OwnerDeny),
|
||||||
|
OwnerSid))
|
||||||
|
goto lasterror;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AddAccessAllowedAce(Acl, ACL_REVISION,
|
||||||
|
FspPosixDefaultPerm | FspPosixMapPermissionToAccessMask(Mode, GroupPerm),
|
||||||
|
GroupSid))
|
||||||
|
goto lasterror;
|
||||||
|
if (GroupDeny)
|
||||||
|
{
|
||||||
|
if (!AddAccessDeniedAce(Acl, ACL_REVISION,
|
||||||
|
FspPosixMapPermissionToAccessMask(Mode, GroupDeny),
|
||||||
|
GroupSid))
|
||||||
|
goto lasterror;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AddAccessAllowedAce(Acl, ACL_REVISION,
|
||||||
|
FspPosixDefaultPerm | FspPosixMapPermissionToAccessMask(Mode, WorldPerm),
|
||||||
|
WorldSid))
|
||||||
|
goto lasterror;
|
||||||
|
|
||||||
|
if (!InitializeSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
|
||||||
|
goto lasterror;
|
||||||
|
|
||||||
|
if (!SetSecurityDescriptorControl(&SecurityDescriptor, SE_DACL_PROTECTED, SE_DACL_PROTECTED))
|
||||||
|
goto lasterror;
|
||||||
|
if (!SetSecurityDescriptorOwner(&SecurityDescriptor, OwnerSid, FALSE))
|
||||||
|
goto lasterror;
|
||||||
|
if (!SetSecurityDescriptorGroup(&SecurityDescriptor, GroupSid, FALSE))
|
||||||
|
goto lasterror;
|
||||||
|
if (!SetSecurityDescriptorDacl(&SecurityDescriptor, TRUE, Acl, FALSE))
|
||||||
|
goto lasterror;
|
||||||
|
|
||||||
|
Size = 0;
|
||||||
|
if (!MakeSelfRelativeSD(&SecurityDescriptor, 0, &Size) &&
|
||||||
|
ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
goto lasterror;
|
||||||
|
|
||||||
|
RelativeSecurityDescriptor = MemAlloc(Size);
|
||||||
|
if (0 == RelativeSecurityDescriptor)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MakeSelfRelativeSD(&SecurityDescriptor, RelativeSecurityDescriptor, &Size))
|
||||||
|
goto lasterror;
|
||||||
|
|
||||||
|
*PSecurityDescriptor = RelativeSecurityDescriptor;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
MemFree(RelativeSecurityDescriptor);
|
||||||
|
|
||||||
|
MemFree(Acl);
|
||||||
|
|
||||||
|
if (0 != WorldSid)
|
||||||
|
FspDeleteSid(WorldSid, FspPosixMapUidToSid);
|
||||||
|
|
||||||
|
if (0 != GroupSid)
|
||||||
|
FspDeleteSid(GroupSid, FspPosixMapUidToSid);
|
||||||
|
|
||||||
|
if (0 != OwnerSid)
|
||||||
|
FspDeleteSid(OwnerSid, FspPosixMapUidToSid);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
lasterror:
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
|
FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user