shared: posix: FspPosixSetUidMap

This commit is contained in:
Bill Zissimopoulos 2022-05-19 00:50:38 +01:00
parent 332ba48203
commit 74bb51ae07
3 changed files with 94 additions and 0 deletions

View File

@ -1835,6 +1835,7 @@ NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem,
/* /*
* POSIX Interop * POSIX Interop
*/ */
FSP_API NTSTATUS FspPosixSetUidMap(UINT32 Uid[], PSID Sid[], ULONG Count);
FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid); FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid);
FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid); FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid);
FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)()); FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)());

View File

@ -34,6 +34,7 @@
#include <shared/ku/library.h> #include <shared/ku/library.h>
FSP_API NTSTATUS FspPosixSetUidMap(UINT32 Uid[], PSID Sid[], ULONG Count);
FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid); FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid);
FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid); FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid);
static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...); static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...);
@ -58,6 +59,7 @@ FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size);
#if defined(_KERNEL_MODE) #if defined(_KERNEL_MODE)
#ifdef ALLOC_PRAGMA #ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspPosixSetUidMap)
#pragma alloc_text(PAGE, FspPosixMapUidToSid) #pragma alloc_text(PAGE, FspPosixMapUidToSid)
#pragma alloc_text(PAGE, FspPosixMapSidToUid) #pragma alloc_text(PAGE, FspPosixMapSidToUid)
#pragma alloc_text(PAGE, FspPosixCreateSid) #pragma alloc_text(PAGE, FspPosixCreateSid)
@ -345,6 +347,8 @@ VOID FspPosixFinalize(BOOLEAN Dynamic)
if (Dynamic) if (Dynamic)
{ {
FspPosixSetUidMap(0, 0, 0);
MemFree(FspTrustedDomains); MemFree(FspTrustedDomains);
MemFree(FspAccountDomainSid); MemFree(FspAccountDomainSid);
MemFree(FspPrimaryDomainSid); MemFree(FspPrimaryDomainSid);
@ -425,6 +429,52 @@ static inline BOOLEAN FspPosixIsRelativeSid(PISID Sid1, PISID Sid2)
return TRUE; return TRUE;
} }
static UINT32 FspPosixUidMap_Uid[8];
static PSID FspPosixUidMap_Sid[8];
static ULONG FspPosixUidMap_Cnt = 0;
FSP_API NTSTATUS FspPosixSetUidMap(UINT32 Uid[], PSID Sid[], ULONG Count)
{
FSP_KU_CODE;
NTSTATUS Result;
if (sizeof FspPosixUidMap_Uid / sizeof FspPosixUidMap_Uid[0] < Count)
Count = sizeof FspPosixUidMap_Uid / sizeof FspPosixUidMap_Uid[0];
for (ULONG I = 0; FspPosixUidMap_Cnt > I; I++)
{
MemFree(FspPosixUidMap_Sid[I]);
FspPosixUidMap_Uid[I] = 0;
FspPosixUidMap_Sid[I] = 0;
}
FspPosixUidMap_Cnt = 0;
for (ULONG I = 0; Count > I; I++)
{
ULONG L = GetLengthSid(Sid[I]);
PSID S = MemAlloc(L);
if (0 == S)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
FspPosixUidMap_Uid[I] = Uid[I];
FspPosixUidMap_Sid[I] = S;
memcpy(S, Sid[I], L);
FspPosixUidMap_Cnt = I + 1;
}
Result = STATUS_SUCCESS;
exit:
if (!NT_SUCCESS(Result))
FspPosixSetUidMap(0, 0, 0);
return Result;
}
FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid) FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
{ {
FSP_KU_CODE; FSP_KU_CODE;
@ -433,6 +483,20 @@ FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
*PSid = 0; *PSid = 0;
/*
* UidMap overrides default UID <-> SID mapping.
*/
for (ULONG I = 0; FspPosixUidMap_Cnt > I; I++)
if (FspPosixUidMap_Uid[I] == Uid)
{
ULONG L = GetLengthSid(FspPosixUidMap_Sid[I]);
PSID S = MemAlloc(L);
if (0 != S)
memcpy(S, FspPosixUidMap_Sid[I], L);
*PSid = S;
goto exit;
}
/* /*
* UID namespace partitioning (from [IDMAP] rules): * UID namespace partitioning (from [IDMAP] rules):
* *
@ -556,6 +620,7 @@ FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
else if (FspUnmappedUid != Uid && 0x1000 <= Uid && Uid < 0x100000) else if (FspUnmappedUid != Uid && 0x1000 <= Uid && Uid < 0x100000)
*PSid = FspPosixCreateSid(5, 2, Uid >> 12, Uid & 0xfff); *PSid = FspPosixCreateSid(5, 2, Uid >> 12, Uid & 0xfff);
exit:
if (0 == *PSid) if (0 == *PSid)
*PSid = FspUnmappedSid; *PSid = FspUnmappedSid;
@ -577,6 +642,16 @@ FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid)
if (!IsValidSid(Sid) || 0 == (Count = *GetSidSubAuthorityCount(Sid))) if (!IsValidSid(Sid) || 0 == (Count = *GetSidSubAuthorityCount(Sid)))
return STATUS_INVALID_SID; return STATUS_INVALID_SID;
/*
* UidMap overrides default UID <-> SID mapping.
*/
for (ULONG I = 0; FspPosixUidMap_Cnt > I; I++)
if (EqualSid(FspPosixUidMap_Sid[I], Sid))
{
*PUid = FspPosixUidMap_Uid[I];
goto exit;
}
Authority = GetSidIdentifierAuthority(Sid)->Value[5]; Authority = GetSidIdentifierAuthority(Sid)->Value[5];
SubAuthority0 = 2 <= Count ? *GetSidSubAuthority(Sid, 0) : 0; SubAuthority0 = 2 <= Count ? *GetSidSubAuthority(Sid, 0) : 0;
Rid = *GetSidSubAuthority(Sid, Count - 1); Rid = *GetSidSubAuthority(Sid, Count - 1);
@ -671,6 +746,7 @@ FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid)
*PUid = 0x10000 + 0x100 * Authority + Rid; *PUid = 0x10000 + 0x100 * Authority + Rid;
} }
exit:
if (-1 == *PUid) if (-1 == *PUid)
*PUid = FspUnmappedUid; *PUid = FspUnmappedUid;

View File

@ -27,6 +27,8 @@
static void posix_map_sid_test(void) static void posix_map_sid_test(void)
{ {
#define TEST_UIDMAP_UID 1000042
#define TEST_UIDMAP_SID L"S-1-12-1-1111-2222-3333-4444"
struct struct
{ {
PWSTR SidStr; PWSTR SidStr;
@ -100,6 +102,7 @@ static void posix_map_sid_test(void)
{ L"S-1-16-16384", 0x64000 }, { L"S-1-16-16384", 0x64000 },
{ L"S-1-16-20480", 0x65000 }, { L"S-1-16-20480", 0x65000 },
{ L"S-1-16-28672", 0x67000 }, { L"S-1-16-28672", 0x67000 },
{ TEST_UIDMAP_SID, TEST_UIDMAP_UID },
{ 0, 0 }, { 0, 0 },
{ 0, 0 }, { 0, 0 },
}; };
@ -112,6 +115,14 @@ static void posix_map_sid_test(void)
PSID Sid0, Sid1; PSID Sid0, Sid1;
UINT32 Uid; UINT32 Uid;
UINT32 UidMap_Uid[1] = { TEST_UIDMAP_UID };
PSID UidMap_Sid[1];
Success = ConvertStringSidToSidW(TEST_UIDMAP_SID, &UidMap_Sid[0]);
ASSERT(Success);
Result = FspPosixSetUidMap(UidMap_Uid, UidMap_Sid, 1);
ASSERT(NT_SUCCESS(Result));
LocalFree(UidMap_Sid[0]);
Success = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token); Success = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token);
ASSERT(Success); ASSERT(Success);
@ -169,6 +180,12 @@ static void posix_map_sid_test(void)
LocalFree(map[sizeof map / sizeof map[0] - 2].SidStr); LocalFree(map[sizeof map / sizeof map[0] - 2].SidStr);
LocalFree(map[sizeof map / sizeof map[0] - 1].SidStr); LocalFree(map[sizeof map / sizeof map[0] - 1].SidStr);
Result = FspPosixSetUidMap(0, 0, 0);
ASSERT(NT_SUCCESS(Result));
#undef TEST_UIDMAP_UID
#undef TEST_UIDMAP_SID
} }
static void posix_map_sd_test(void) static void posix_map_sd_test(void)