diff --git a/build/VStudio/winfsp_dll.vcxproj b/build/VStudio/winfsp_dll.vcxproj
index ed328627..01207f5b 100644
--- a/build/VStudio/winfsp_dll.vcxproj
+++ b/build/VStudio/winfsp_dll.vcxproj
@@ -35,6 +35,7 @@
+
@@ -51,7 +52,6 @@
-
@@ -63,6 +63,7 @@
+
diff --git a/build/VStudio/winfsp_dll.vcxproj.filters b/build/VStudio/winfsp_dll.vcxproj.filters
index 3340618e..cac6502a 100644
--- a/build/VStudio/winfsp_dll.vcxproj.filters
+++ b/build/VStudio/winfsp_dll.vcxproj.filters
@@ -27,6 +27,9 @@
{96091a7b-3923-4a74-9491-3ee230c688f9}
+
+ {613cce77-2428-4f9a-9187-f37e009253c1}
+
@@ -77,6 +80,9 @@
Source\fuse3
+
+ Source\ku
+
@@ -124,9 +130,6 @@
Source\fuse
-
- Source
-
Source\fuse
@@ -154,6 +157,9 @@
Source\fuse3
+
+ Source\ku
+
diff --git a/build/VStudio/winfsp_sys.vcxproj b/build/VStudio/winfsp_sys.vcxproj
index 2f04da2c..e341f18d 100644
--- a/build/VStudio/winfsp_sys.vcxproj
+++ b/build/VStudio/winfsp_sys.vcxproj
@@ -155,6 +155,7 @@
+
@@ -190,6 +191,7 @@
+
diff --git a/build/VStudio/winfsp_sys.vcxproj.filters b/build/VStudio/winfsp_sys.vcxproj.filters
index 866dfa01..a6d6528e 100644
--- a/build/VStudio/winfsp_sys.vcxproj.filters
+++ b/build/VStudio/winfsp_sys.vcxproj.filters
@@ -12,6 +12,9 @@
{904f0df1-2fb8-4f84-aa46-fa929488c39a}
+
+ {235076b8-290c-4dec-b005-71d9b8e8cba7}
+
@@ -107,6 +110,9 @@
Source
+
+ Source\ku
+
@@ -118,6 +124,9 @@
Include\winfsp
+
+ Source\ku
+
diff --git a/opt/fsext/inc/winfsp/fsext.h b/opt/fsext/inc/winfsp/fsext.h
index e16b18b8..5344795d 100644
--- a/opt/fsext/inc/winfsp/fsext.h
+++ b/opt/fsext/inc/winfsp/fsext.h
@@ -51,10 +51,43 @@ typedef struct
UINT32 DeviceExtensionOffset;
} FSP_FSEXT_PROVIDER;
-FSP_DDI_DEF(NTSTATUS, FspFsextProviderRegister, FSP_FSEXT_PROVIDER *Provider)
+FSP_DDI_DEF(NTSTATUS, FspFsextProviderRegister,
+ FSP_FSEXT_PROVIDER *Provider)
-FSP_DDI_DEF(NTSTATUS, FspPosixMapSidToUid, PSID Sid, PUINT32 PUid)
-FSP_DDI_DEF(NTSTATUS, FspPosixMapWindowsToPosixPathEx, PWSTR WindowsPath, char **PPosixPath,
+FSP_DDI_DEF(NTSTATUS, FspPosixMapUidToSid,
+ UINT32 Uid,
+ PSID *PSid)
+FSP_DDI_DEF(NTSTATUS, FspPosixMapSidToUid,
+ PSID Sid,
+ PUINT32 PUid)
+FSP_DDI_DEF(VOID, FspDeleteSid,
+ PSID Sid,
+ NTSTATUS (*CreateFunc)())
+FSP_DDI_DEF(NTSTATUS, FspPosixMapPermissionsToSecurityDescriptor,
+ UINT32 Uid,
+ UINT32 Gid,
+ UINT32 Mode,
+ PSECURITY_DESCRIPTOR *PSecurityDescriptor)
+FSP_DDI_DEF(NTSTATUS, FspPosixMapSecurityDescriptorToPermissions,
+ PSECURITY_DESCRIPTOR SecurityDescriptor,
+ PUINT32 PUid,
+ PUINT32 PGid,
+ PUINT32 PMode)
+FSP_DDI_DEF(NTSTATUS, FspPosixMapWindowsToPosixPathEx,
+ PWSTR WindowsPath,
+ char **PPosixPath,
BOOLEAN Translate)
+FSP_DDI_DEF(NTSTATUS, FspPosixMapPosixToWindowsPathEx,
+ const char *PosixPath,
+ PWSTR *PWindowsPath,
+ BOOLEAN Translate)
+FSP_DDI_DEF(VOID, FspPosixDeletePath,
+ void *Path)
+FSP_DDI_DEF(VOID, FspPosixEncodeWindowsPath,
+ PWSTR WindowsPath,
+ ULONG Size)
+FSP_DDI_DEF(VOID, FspPosixDecodeWindowsPath,
+ PWSTR WindowsPath,
+ ULONG Size)
#endif
diff --git a/opt/fsext/lib/winfsp-x64.lib b/opt/fsext/lib/winfsp-x64.lib
index a471199d..a1192e27 100644
Binary files a/opt/fsext/lib/winfsp-x64.lib and b/opt/fsext/lib/winfsp-x64.lib differ
diff --git a/opt/fsext/lib/winfsp-x86.lib b/opt/fsext/lib/winfsp-x86.lib
index 5d206559..f34538f0 100644
Binary files a/opt/fsext/lib/winfsp-x86.lib and b/opt/fsext/lib/winfsp-x86.lib differ
diff --git a/src/ku/library.h b/src/ku/library.h
new file mode 100644
index 00000000..1a95a94d
--- /dev/null
+++ b/src/ku/library.h
@@ -0,0 +1,222 @@
+/**
+ * @file ku/library.h
+ *
+ * @copyright 2015-2019 Bill Zissimopoulos
+ */
+/*
+ * This file is part of WinFsp.
+ *
+ * You can redistribute it and/or modify it under the terms of the GNU
+ * General Public License version 3 as published by the Free Software
+ * Foundation.
+ *
+ * Licensees holding a valid commercial license may use this software
+ * in accordance with the commercial license agreement provided in
+ * conjunction with the software. The terms and conditions of any such
+ * commercial license agreement shall govern, supersede, and render
+ * ineffective any application of the GPLv3 license to this software,
+ * notwithstanding of any reference thereto in the software or
+ * associated repository.
+ */
+
+#ifndef WINFSP_KU_LIBRARY_H_INCLUDED
+#define WINFSP_KU_LIBRARY_H_INCLUDED
+
+#if !defined(_KERNEL_MODE)
+
+#include
+#include
+#define _NTDEF_
+#include
+
+#define FSP_KU_CODE ((void)0)
+
+#else
+
+#include
+
+#define FSP_KU_CODE PAGED_CODE(); NTSTATUS fsp_ku_status = STATUS_SUCCESS; (VOID)fsp_ku_status
+
+#define FSP_API FSP_DDI
+
+#define BYTE UINT8
+#define BOOL BOOLEAN
+#define LPBOOL PBOOLEAN
+#define UINT ULONG
+
+#define GetLastError() ((DWORD)fsp_ku_status)
+#define FspNtStatusFromWin32(Err) ((NTSTATUS)(Err))
+#define ERROR_INSUFFICIENT_BUFFER STATUS_BUFFER_TOO_SMALL
+
+#define InitOnceExecuteOnce(I, F, P, C) RtlRunOnceExecuteOnce(I, F, P, C)
+#define INIT_ONCE RTL_RUN_ONCE
+#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT
+
+#define AddAccessAllowedAce(Acl, Rev, Acc, Sid)\
+ (fsp_ku_status = RtlAddAccessAllowedAce(Acl, Rev, Acc, Sid),\
+ NT_SUCCESS(fsp_ku_status))
+#define AddAccessDeniedAce(Acl, Rev, Acc, Sid)\
+ (fsp_ku_status = FspKuAddAccessDeniedAce(Acl, Rev, Acc, Sid),\
+ NT_SUCCESS(fsp_ku_status))
+#define EqualSid(Sid1, Sid2) (fsp_ku_status = 0, RtlEqualSid(Sid1, Sid2))
+#define GetAce(Acl, Idx, Ace) (fsp_ku_status = RtlGetAce(Acl, Idx, Ace), NT_SUCCESS(fsp_ku_status))
+#define GetAclInformation(Acl, Inf, Len, Cls)\
+ (fsp_ku_status = FspKuQueryInformationAcl(Acl, Inf, Len, Cls),\
+ NT_SUCCESS(fsp_ku_status))
+#define GetLengthSid(Sid) (fsp_ku_status = 0, RtlLengthSid(Sid))
+#define GetSecurityDescriptorDacl(Sec, Prs, Dac, Def)\
+ (fsp_ku_status = RtlGetDaclSecurityDescriptor(Sec, Prs, Dac, Def),\
+ NT_SUCCESS(fsp_ku_status))
+#define GetSecurityDescriptorGroup(Sec, Grp, Def)\
+ (fsp_ku_status = RtlGetGroupSecurityDescriptor(Sec, Grp, Def),\
+ NT_SUCCESS(fsp_ku_status))
+#define GetSecurityDescriptorOwner(Sec, Own, Def)\
+ (fsp_ku_status = RtlGetOwnerSecurityDescriptor(Sec, Own, Def),\
+ NT_SUCCESS(fsp_ku_status))
+#define GetSidIdentifierAuthority(Sid) (fsp_ku_status = 0, &((PISID)(Sid))->IdentifierAuthority)
+#define GetSidSubAuthority(Sid, Sub) (fsp_ku_status = 0, RtlSubAuthoritySid(Sid, Sub))
+#define GetSidSubAuthorityCount(Sid) (fsp_ku_status = 0, RtlSubAuthorityCountSid(Sid))
+#define InitializeAcl(Acl, Len, Rev) (fsp_ku_status = RtlCreateAcl(Acl, Len, Rev), NT_SUCCESS(fsp_ku_status))
+#define InitializeSecurityDescriptor(Sec, Rev)\
+ (fsp_ku_status = RtlCreateSecurityDescriptor(Sec, Rev),\
+ NT_SUCCESS(fsp_ku_status))
+#define InitializeSid(Sid, Aut, Cnt) (fsp_ku_status = RtlInitializeSid(Sid, Aut, Cnt), NT_SUCCESS(fsp_ku_status))
+#define IsValidSid(Sid) (RtlValidSid(Sid) || (fsp_ku_status = STATUS_INVALID_SID, FALSE))
+#define MakeSelfRelativeSD(Abs, Rel, Len)\
+ (fsp_ku_status = RtlAbsoluteToSelfRelativeSD(Abs, Rel, Len),\
+ NT_SUCCESS(fsp_ku_status))
+#define SetSecurityDescriptorControl(Sec, Msk, Bit)\
+ (fsp_ku_status = FspKuSetControlSecurityDescriptor(Sec, Msk, Bit),\
+ NT_SUCCESS(fsp_ku_status))
+#define SetSecurityDescriptorDacl(Sec, Prs, Dac, Def)\
+ (fsp_ku_status = RtlSetDaclSecurityDescriptor(Sec, Prs, Dac, Def),\
+ NT_SUCCESS(fsp_ku_status))
+#define SetSecurityDescriptorGroup(Sec, Grp, Def)\
+ (fsp_ku_status = RtlSetGroupSecurityDescriptor(Sec, Grp, Def),\
+ NT_SUCCESS(fsp_ku_status))
+#define SetSecurityDescriptorOwner(Sec, Own, Def)\
+ (fsp_ku_status = RtlSetOwnerSecurityDescriptor(Sec, Own, Def),\
+ NT_SUCCESS(fsp_ku_status))
+static inline NTSTATUS FspKuAddAccessDeniedAce(
+ PACL Acl,
+ ULONG AceRevision,
+ ACCESS_MASK AccessMask,
+ PSID Sid)
+{
+ /* We are missing RtlAddAccessDeniedAce. So we need this malarkey! */
+ NTSTATUS Result;
+ PACE_HEADER Ace;
+ Result = RtlAddAccessAllowedAce(Acl, AceRevision, AccessMask, Sid);
+ if (!NT_SUCCESS(Result))
+ return Result;
+ Result = RtlGetAce(Acl, Acl->AceCount - 1, &Ace);
+ if (!NT_SUCCESS(Result))
+ return Result;
+ Ace->AceType = ACCESS_DENIED_ACE_TYPE;
+ return STATUS_SUCCESS;
+}
+typedef enum
+{
+ AclRevisionInformation__DO_NOT_USE = 1,
+ AclSizeInformation,
+} ACL_INFORMATION_CLASS;
+typedef struct
+{
+ DWORD AceCount;
+ DWORD AclBytesInUse__DO_NOT_USE;
+ DWORD AclBytesFree__DO_NOT_USE;
+} ACL_SIZE_INFORMATION, *PACL_SIZE_INFORMATION;
+static inline NTSTATUS FspKuQueryInformationAcl(
+ PACL Acl,
+ PVOID AclInformation,
+ ULONG AclInformationLength,
+ ACL_INFORMATION_CLASS AclInformationClass)
+{
+ ASSERT(AclSizeInformation == AclInformationClass);
+ ASSERT(sizeof(ACL_SIZE_INFORMATION) <= AclInformationLength);
+ ((PACL_SIZE_INFORMATION)AclInformation)->AceCount = Acl->AceCount;
+ return STATUS_SUCCESS;
+}
+static inline NTSTATUS FspKuSetControlSecurityDescriptor(
+ PSECURITY_DESCRIPTOR SecurityDescriptor,
+ SECURITY_DESCRIPTOR_CONTROL ControlMask,
+ SECURITY_DESCRIPTOR_CONTROL ControlBits)
+{
+ ((PUSHORT)(SecurityDescriptor))[1] &= ~ControlMask;
+ ((PUSHORT)(SecurityDescriptor))[1] |= ControlBits;
+ return STATUS_SUCCESS;
+}
+
+#define WideCharToMultiByte(C, F, W, w, B, b, D, d)\
+ (FspKuWideCharToMultiByte(C, F, W, w, B, b, D, d, &fsp_ku_status))
+#define MultiByteToWideChar(C, F, B, b, W, w)\
+ (FspKuMultiByteToWideChar(C, F, B, b, W, w, &fsp_ku_status))
+#define CP_UTF8 65001
+static inline int FspKuWideCharToMultiByte(
+ UINT CodePage,
+ DWORD dwFlags,
+ LPCWCH lpWideCharStr,
+ int cchWideChar,
+ LPSTR lpMultiByteStr,
+ int cbMultiByte,
+ LPCCH lpDefaultChar,
+ LPBOOL lpUsedDefaultChar,
+ PNTSTATUS PResult)
+{
+ ASSERT(CP_UTF8 == CodePage);
+ ASSERT(0 == dwFlags);
+ ASSERT(0 == lpDefaultChar);
+ ASSERT(0 == lpUsedDefaultChar);
+ NTSTATUS Result;
+ ULONG ByteCount;
+ if (-1 == cchWideChar)
+ cchWideChar = (int)wcslen(lpWideCharStr);
+ Result = RtlUnicodeToUTF8N(
+ lpMultiByteStr, cbMultiByte, &ByteCount,
+ lpWideCharStr, cchWideChar * sizeof(WCHAR));
+ if (STATUS_SOME_NOT_MAPPED == Result)
+ Result = STATUS_SUCCESS;
+ else if (!NT_SUCCESS(Result))
+ return 0;
+ *PResult = Result;
+ return ByteCount;
+}
+static inline int FspKuMultiByteToWideChar(
+ UINT CodePage,
+ DWORD dwFlags,
+ LPCCH lpMultiByteStr,
+ int cbMultiByte,
+ LPWSTR lpWideCharStr,
+ int cchWideChar,
+ PNTSTATUS PResult)
+{
+ ASSERT(CP_UTF8 == CodePage);
+ ASSERT(0 == dwFlags);
+ NTSTATUS Result;
+ ULONG ByteCount;
+ if (-1 == cbMultiByte)
+ cbMultiByte = (int)strlen(lpMultiByteStr);
+ Result = RtlUTF8ToUnicodeN(
+ lpWideCharStr, cchWideChar * sizeof(WCHAR), &ByteCount,
+ lpMultiByteStr, cbMultiByte);
+ if (STATUS_SOME_NOT_MAPPED == Result)
+ Result = STATUS_SUCCESS;
+ else if (!NT_SUCCESS(Result))
+ return 0;
+ *PResult = Result;
+ return ByteCount / sizeof(WCHAR);
+}
+
+static inline void *MemAlloc(size_t Size)
+{
+ return FspAlloc(Size);
+}
+static inline void MemFree(void *Pointer)
+{
+ if (0 != Pointer)
+ FspFree(Pointer);
+}
+
+#endif
+
+#endif
diff --git a/src/dll/posix.c b/src/ku/posix.c
similarity index 85%
rename from src/dll/posix.c
rename to src/ku/posix.c
index f7a58f85..6322ff42 100644
--- a/src/dll/posix.c
+++ b/src/ku/posix.c
@@ -1,5 +1,5 @@
/**
- * @file dll/posix.c
+ * @file ku/posix.c
* POSIX Interop.
*
* This file provides routines for Windows/POSIX interoperability. It is based
@@ -32,15 +32,67 @@
* associated repository.
*/
-#include
-#include
-#define _NTDEF_
-#include
+#include
+FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid);
+FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid);
static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...);
+FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)());
+FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
+ UINT32 Uid, UINT32 Gid, UINT32 Mode,
+ PSECURITY_DESCRIPTOR *PSecurityDescriptor);
+FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
+ PSECURITY_DESCRIPTOR SecurityDescriptor,
+ PUINT32 PUid, PUINT32 PGid, PUINT32 PMode);
+FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath,
+ BOOLEAN Translate);
+FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath,
+ BOOLEAN Translate);
+FSP_API VOID FspPosixDeletePath(void *Path);
+FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size);
+FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size);
-static INIT_ONCE FspPosixInitOnce = INIT_ONCE_STATIC_INIT;
-union
+#if defined(_KERNEL_MODE)
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, FspPosixMapUidToSid)
+#pragma alloc_text(PAGE, FspPosixMapSidToUid)
+#pragma alloc_text(PAGE, FspPosixCreateSid)
+#pragma alloc_text(PAGE, FspDeleteSid)
+#pragma alloc_text(PAGE, FspPosixMapPermissionsToSecurityDescriptor)
+#pragma alloc_text(PAGE, FspPosixMapSecurityDescriptorToPermissions)
+#pragma alloc_text(PAGE, FspPosixMapWindowsToPosixPathEx)
+#pragma alloc_text(PAGE, FspPosixMapPosixToWindowsPathEx)
+#pragma alloc_text(PAGE, FspPosixDeletePath)
+#pragma alloc_text(PAGE, FspPosixEncodeWindowsPath)
+#pragma alloc_text(PAGE, FspPosixDecodeWindowsPath)
+#endif
+#endif
+
+static union
+{
+ SID V;
+ UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))];
+} FspWorldSidBuf =
+{
+ /* S-1-1-0 */
+ .V.Revision = SID_REVISION,
+ .V.SubAuthorityCount = 1,
+ .V.IdentifierAuthority.Value[5] = 1,
+ .V.SubAuthority[0] = 0,
+};
+static union
+{
+ SID V;
+ UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))];
+} FspAuthUsersSidBuf =
+{
+ /* S-1-5-11 */
+ .V.Revision = SID_REVISION,
+ .V.SubAuthorityCount = 1,
+ .V.IdentifierAuthority.Value[5] = 5,
+ .V.SubAuthority[0] = 11,
+};
+static union
{
SID V;
UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))];
@@ -52,11 +104,15 @@ union
.V.IdentifierAuthority.Value[5] = 0,
.V.SubAuthority[0] = 65534,
};
-static PISID FspAccountDomainSid, FspPrimaryDomainSid;
+#define FspWorldSid (&FspWorldSidBuf.V)
+#define FspAuthUsersSid (&FspAuthUsersSidBuf.V)
#define FspUnmappedSid (&FspUnmappedSidBuf.V)
#define FspUnmappedUid (65534)
+static PISID FspAccountDomainSid, FspPrimaryDomainSid;
+static INIT_ONCE FspPosixInitOnce = INIT_ONCE_STATIC_INIT;
+#if !defined(_KERNEL_MODE)
static BOOL WINAPI FspPosixInitialize(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{
@@ -120,9 +176,79 @@ VOID FspPosixFinalize(BOOLEAN Dynamic)
MemFree(FspPrimaryDomainSid);
}
}
+#else
+ULONG NTAPI FspPosixInitialize(
+ PRTL_RUN_ONCE RunOnce, PVOID Parameter, PVOID *Context)
+{
+ static union
+ {
+ SID V;
+ UINT8 B[SECURITY_MAX_SID_SIZE];
+ } FspAccountDomainSidBuf;
+ static union
+ {
+ SID V;
+ UINT8 B[SECURITY_MAX_SID_SIZE];
+ } FspPrimaryDomainSidBuf;
+ UNICODE_STRING Path;
+ UNICODE_STRING Name;
+ union
+ {
+ KEY_VALUE_PARTIAL_INFORMATION V;
+ UINT8 B[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + SECURITY_MAX_SID_SIZE];
+ } Value;
+ ULONG Length;
+ NTSTATUS Result;
+
+ RtlInitUnicodeString(&Path, L"\\Machine\\SECURITY\\Policy\\PolAcDmS");
+ RtlZeroMemory(&Name, sizeof Name);
+ Length = sizeof Value;
+ Result = FspRegistryGetValue(&Path, &Name, &Value.V, &Length);
+ if (STATUS_SUCCESS == Result /*!NT_SUCCESS*/ && REG_NONE == Value.V.Type &&
+ sizeof(SID) <= Value.V.DataLength && RtlValidSid((PSID)&Value.V.Data))
+ {
+ RtlCopyMemory(&FspAccountDomainSidBuf.V, &Value.V.Data, Value.V.DataLength);
+ FspAccountDomainSid = &FspAccountDomainSidBuf.V;
+ }
+
+ RtlInitUnicodeString(&Path, L"\\Machine\\SECURITY\\Policy\\PolPrDmS");
+ RtlZeroMemory(&Name, sizeof Name);
+ Length = sizeof Value;
+ Result = FspRegistryGetValue(&Path, &Name, &Value.V, &Length);
+ if (STATUS_SUCCESS == Result /*!NT_SUCCESS*/ && REG_NONE == Value.V.Type &&
+ sizeof(SID) <= Value.V.DataLength && RtlValidSid((PSID)&Value.V.Data))
+ {
+ RtlCopyMemory(&FspPrimaryDomainSidBuf.V, &Value.V.Data, Value.V.DataLength);
+ FspPrimaryDomainSid = &FspPrimaryDomainSidBuf.V;
+ }
+
+ return TRUE;
+}
+#endif
+
+static inline BOOLEAN FspPosixIsRelativeSid(PISID Sid1, PISID Sid2)
+{
+ if (Sid1->Revision != Sid2->Revision)
+ return FALSE;
+ if (Sid1->IdentifierAuthority.Value[0] != Sid2->IdentifierAuthority.Value[0] ||
+ Sid1->IdentifierAuthority.Value[1] != Sid2->IdentifierAuthority.Value[1] ||
+ Sid1->IdentifierAuthority.Value[2] != Sid2->IdentifierAuthority.Value[2] ||
+ Sid1->IdentifierAuthority.Value[3] != Sid2->IdentifierAuthority.Value[3] ||
+ Sid1->IdentifierAuthority.Value[4] != Sid2->IdentifierAuthority.Value[4] ||
+ Sid1->IdentifierAuthority.Value[5] != Sid2->IdentifierAuthority.Value[5])
+ return FALSE;
+ if (Sid1->SubAuthorityCount + 1 != Sid2->SubAuthorityCount)
+ return FALSE;
+ for (ULONG I = 0; Sid1->SubAuthorityCount > I; I++)
+ if (Sid1->SubAuthority[I] != Sid2->SubAuthority[I])
+ return FALSE;
+ return TRUE;
+}
FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
{
+ FSP_KU_CODE;
+
InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0);
*PSid = 0;
@@ -221,7 +347,7 @@ FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
* S-1-X-Y <=> uid/gid: 0x10000 + 0x100 * X + Y
*/
else if (0x10000 <= Uid && Uid < 0x11000)
- *PSid = FspPosixCreateSid((Uid - 0x10000) >> 8, 1, (Uid - 0x10000) & 0xff);
+ *PSid = FspPosixCreateSid((BYTE)((Uid - 0x10000) >> 8), 1, (Uid - 0x10000) & 0xff);
/* [IDMAP]
* Other well-known SIDs in the NT_AUTHORITY domain (S-1-5-X-RID):
@@ -238,13 +364,15 @@ FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid)
{
+ FSP_KU_CODE;
+
InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0);
BYTE Authority;
BYTE Count;
UINT32 SubAuthority0, Rid;
- *PUid = -1;
+ *PUid = (UINT32)-1;
if (!IsValidSid(Sid) || 0 == (Count = *GetSidSubAuthorityCount(Sid)))
return STATUS_INVALID_SID;
@@ -298,12 +426,11 @@ FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid)
* has PrimaryDomainSid == AccountDomainSid.
*/
- BOOL EqualDomains = FALSE;
if (0 != FspPrimaryDomainSid &&
- EqualDomainSid(FspPrimaryDomainSid, Sid, &EqualDomains) && EqualDomains)
+ FspPosixIsRelativeSid(FspPrimaryDomainSid, Sid))
*PUid = 0x100000 + Rid;
else if (0 != FspAccountDomainSid &&
- EqualDomainSid(FspAccountDomainSid, Sid, &EqualDomains) && EqualDomains)
+ FspPosixIsRelativeSid(FspAccountDomainSid, Sid))
*PUid = 0x30000 + Rid;
/*
@@ -348,6 +475,8 @@ FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid)
static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...)
{
+ FSP_KU_CODE;
+
PISID Sid;
SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
va_list ap;
@@ -370,6 +499,8 @@ static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...)
FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)())
{
+ FSP_KU_CODE;
+
if (FspUnmappedSid == Sid)
;
else if ((NTSTATUS (*)())FspPosixMapUidToSid == CreateFunc)
@@ -439,7 +570,9 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
UINT32 Uid, UINT32 Gid, UINT32 Mode,
PSECURITY_DESCRIPTOR *PSecurityDescriptor)
{
- PSID OwnerSid = 0, GroupSid = 0, WorldSid = 0;
+ FSP_KU_CODE;
+
+ PSID OwnerSid = 0, GroupSid = 0;
UINT32 OwnerPerm, OwnerDeny, GroupPerm, GroupDeny, WorldPerm;
PACL Acl = 0;
SECURITY_DESCRIPTOR SecurityDescriptor;
@@ -457,13 +590,6 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
if (!NT_SUCCESS(Result))
goto exit;
- WorldSid = FspWksidGet(WinWorldSid);
- if (0 == WorldSid)
- {
- Result = STATUS_INSUFFICIENT_RESOURCES;
- goto exit;
- }
-
OwnerPerm = (Mode & 0700) >> 6;
GroupPerm = (Mode & 0070) >> 3;
WorldPerm = (Mode & 0007);
@@ -502,7 +628,7 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
sizeof(ACCESS_DENIED_ACE) * (!!OwnerDeny + !!GroupDeny);
Size += GetLengthSid(OwnerSid) - sizeof(DWORD);
Size += GetLengthSid(GroupSid) - sizeof(DWORD);
- Size += GetLengthSid(WorldSid) - sizeof(DWORD);
+ Size += GetLengthSid(FspWorldSid) - sizeof(DWORD);
if (OwnerDeny)
Size += GetLengthSid(OwnerSid) - sizeof(DWORD);
if (GroupDeny)
@@ -546,7 +672,7 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
if (!AddAccessAllowedAce(Acl, ACL_REVISION,
FspPosixDefaultPerm | FspPosixMapPermissionToAccessMask(Mode, WorldPerm),
- WorldSid))
+ FspWorldSid))
goto lasterror;
if (!InitializeSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
@@ -621,7 +747,9 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
PSECURITY_DESCRIPTOR SecurityDescriptor,
PUINT32 PUid, PUINT32 PGid, PUINT32 PMode)
{
- PSID OwnerSid = 0, GroupSid = 0, WorldSid = 0, AuthUsersSid = 0;
+ FSP_KU_CODE;
+
+ PSID OwnerSid = 0, GroupSid = 0;
BOOL Defaulted, DaclPresent;
PACL Acl = 0;
ACL_SIZE_INFORMATION AclSizeInfo;
@@ -653,20 +781,6 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
if (0 != Acl)
{
- WorldSid = FspWksidGet(WinWorldSid);
- if (0 == WorldSid)
- {
- Result = STATUS_INSUFFICIENT_RESOURCES;
- goto exit;
- }
-
- AuthUsersSid = FspWksidGet(WinAuthenticatedUserSid);
- if (0 == AuthUsersSid)
- {
- Result = STATUS_INSUFFICIENT_RESOURCES;
- goto exit;
- }
-
OwnerAllow = OwnerDeny = GroupAllow = GroupDeny = WorldAllow = WorldDeny = 0;
if (!GetAclInformation(Acl, &AclSizeInfo, sizeof AclSizeInfo, AclSizeInformation))
@@ -701,7 +815,7 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
* add the allowed or denied access right bits into the "owner", "group"
* and "other" collections.
*/
- if (EqualSid(WorldSid, AceSid) || EqualSid(AuthUsersSid, AceSid))
+ if (EqualSid(FspWorldSid, AceSid) || EqualSid(FspAuthUsersSid, AceSid))
{
/* [PERMS]
* If this is an access-denied ACE, then add each access right to the set
@@ -812,6 +926,8 @@ static UINT32 FspPosixInvalidPathChars[4] =
FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath,
BOOLEAN Translate)
{
+ FSP_KU_CODE;
+
NTSTATUS Result;
ULONG Size;
char *PosixPath = 0, *p, *q;
@@ -874,6 +990,8 @@ lasterror:
FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath,
BOOLEAN Translate)
{
+ FSP_KU_CODE;
+
NTSTATUS Result;
ULONG Size;
PWSTR WindowsPath = 0, p;
@@ -925,11 +1043,15 @@ lasterror:
FSP_API VOID FspPosixDeletePath(void *Path)
{
+ FSP_KU_CODE;
+
MemFree(Path);
}
FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size)
{
+ FSP_KU_CODE;
+
for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++)
{
WCHAR c = *p;
@@ -944,6 +1066,8 @@ FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size)
FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size)
{
+ FSP_KU_CODE;
+
for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++)
{
WCHAR c = *p;
diff --git a/src/sys/driver.h b/src/sys/driver.h
index 1e7c4897..b242d417 100644
--- a/src/sys/driver.h
+++ b/src/sys/driver.h
@@ -493,6 +493,8 @@ PVOID FspAllocateIrpMustSucceed(CCHAR StackSize);
NTSTATUS FspCreateGuid(GUID *Guid);
NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess,
PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject);
+NTSTATUS FspRegistryGetValue(PUNICODE_STRING Path, PUNICODE_STRING ValueName,
+ PKEY_VALUE_PARTIAL_INFORMATION ValueInformation, PULONG PValueInformationLength);
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length);
NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
diff --git a/src/sys/util.c b/src/sys/util.c
index a99c42c8..92ddcc04 100644
--- a/src/sys/util.c
+++ b/src/sys/util.c
@@ -24,6 +24,8 @@
NTSTATUS FspCreateGuid(GUID *Guid);
NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess,
PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject);
+NTSTATUS FspRegistryGetValue(PUNICODE_STRING Path, PUNICODE_STRING ValueName,
+ PKEY_VALUE_PARTIAL_INFORMATION ValueInformation, PULONG PValueInformationLength);
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length);
NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
@@ -130,6 +132,7 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspCreateGuid)
#pragma alloc_text(PAGE, FspGetDeviceObjectPointer)
+#pragma alloc_text(PAGE, FspRegistryGetValue)
#pragma alloc_text(PAGE, FspSendSetInformationIrp)
#pragma alloc_text(PAGE, FspSendQuerySecurityIrp)
#pragma alloc_text(PAGE, FspSendQueryEaIrp)
@@ -280,6 +283,37 @@ NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK Desir
return Result;
}
+NTSTATUS FspRegistryGetValue(PUNICODE_STRING Path, PUNICODE_STRING ValueName,
+ PKEY_VALUE_PARTIAL_INFORMATION ValueInformation, PULONG PValueInformationLength)
+{
+ PAGED_CODE();
+
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE Handle = 0;
+ NTSTATUS Result;
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ Path, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0);
+
+ Result = ZwOpenKey(&Handle, KEY_QUERY_VALUE, &ObjectAttributes);
+ if (!NT_SUCCESS(Result))
+ goto exit;
+
+ Result = ZwQueryValueKey(Handle, ValueName,
+ KeyValuePartialInformation, ValueInformation,
+ *PValueInformationLength, PValueInformationLength);
+ if (!NT_SUCCESS(Result))
+ goto exit;
+
+ Result = STATUS_SUCCESS;
+
+exit:
+ if (0 != Handle)
+ ZwClose(Handle);
+
+ return Result;
+}
+
typedef struct
{
IO_STATUS_BLOCK IoStatus;