diff --git a/build/VStudio/winfsp_dll.vcxproj b/build/VStudio/winfsp_dll.vcxproj
index 7bee8cb9..784bfe71 100644
--- a/build/VStudio/winfsp_dll.vcxproj
+++ b/build/VStudio/winfsp_dll.vcxproj
@@ -51,6 +51,7 @@
+
diff --git a/build/VStudio/winfsp_dll.vcxproj.filters b/build/VStudio/winfsp_dll.vcxproj.filters
index 4b1f7e2b..b93ce5e2 100644
--- a/build/VStudio/winfsp_dll.vcxproj.filters
+++ b/build/VStudio/winfsp_dll.vcxproj.filters
@@ -112,6 +112,9 @@
Source\fuse
+
+ Source
+
diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h
index 9fd5b97f..5b25d8cb 100644
--- a/inc/winfsp/winfsp.h
+++ b/inc/winfsp/winfsp.h
@@ -1700,6 +1700,7 @@ FSP_API VOID FspEventLogV(ULONG Type, PWSTR Format, va_list ap);
FSP_API VOID FspDebugLogSetHandle(HANDLE Handle);
FSP_API VOID FspDebugLog(const char *Format, ...);
FSP_API VOID FspDebugLogSD(const char *Format, PSECURITY_DESCRIPTOR SecurityDescriptor);
+FSP_API VOID FspDebugLogSid(const char *format, PSID Sid);
FSP_API VOID FspDebugLogFT(const char *Format, PFILETIME FileTime);
FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request);
FSP_API VOID FspDebugLogResponse(FSP_FSCTL_TRANSACT_RSP *Response);
diff --git a/src/dll/debug.c b/src/dll/debug.c
index ff8c98f5..5960a5b3 100644
--- a/src/dll/debug.c
+++ b/src/dll/debug.c
@@ -63,6 +63,21 @@ FSP_API VOID FspDebugLogSD(const char *format, PSECURITY_DESCRIPTOR SecurityDesc
FspDebugLog(format, "invalid security descriptor");
}
+FSP_API VOID FspDebugLogSid(const char *format, PSID Sid)
+{
+ char *S;
+
+ if (0 == Sid)
+ FspDebugLog(format, "null SID");
+ else if (ConvertSidToStringSidA(Sid, &S))
+ {
+ FspDebugLog(format, S);
+ LocalFree(S);
+ }
+ else
+ FspDebugLog(format, "invalid SID");
+}
+
FSP_API VOID FspDebugLogFT(const char *format, PFILETIME FileTime)
{
SYSTEMTIME SystemTime;
diff --git a/src/dll/fsctl.c b/src/dll/fsctl.c
index 56668cc9..26ff3acc 100644
--- a/src/dll/fsctl.c
+++ b/src/dll/fsctl.c
@@ -284,7 +284,7 @@ static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
* This function adds an ACE that allows Everyone to start a service.
*/
- PSID WorldSid = 0;
+ PSID WorldSid;
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
EXPLICIT_ACCESSW AccessEntry;
@@ -296,18 +296,12 @@ static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
NTSTATUS Result;
/* get the Everyone (World) SID */
- Size = SECURITY_MAX_SID_SIZE;
- WorldSid = MemAlloc(Size);
+ WorldSid = FspWksidGet(WinWorldSid);
if (0 == WorldSid)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
- if (!CreateWellKnownSid(WinWorldSid, 0, WorldSid, &Size))
- {
- Result = FspNtStatusFromWin32(GetLastError());
- goto exit;
- }
/* get the service security descriptor DACL */
Size = 0;
@@ -394,7 +388,6 @@ static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
exit:
LocalFree(NewSecurityDescriptor);
MemFree(SecurityDescriptor);
- MemFree(WorldSid);
return Result;
}
diff --git a/src/dll/library.c b/src/dll/library.c
index 5e5c113e..ea56c177 100644
--- a/src/dll/library.c
+++ b/src/dll/library.c
@@ -44,6 +44,7 @@ BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
FspServiceFinalize(Dynamic);
FspEventLogFinalize(Dynamic);
FspPosixFinalize(Dynamic);
+ FspWksidFinalize(Dynamic);
break;
case DLL_THREAD_DETACH:
diff --git a/src/dll/library.h b/src/dll/library.h
index b3c1376c..e82901d1 100644
--- a/src/dll/library.h
+++ b/src/dll/library.h
@@ -31,11 +31,15 @@
FspDebugLog("[U] " LIBRARY_NAME "!" __FUNCTION__ ": " fmt "\n", __VA_ARGS__)
#define DEBUGLOGSD(fmt, SD) \
FspDebugLogSD("[U] " LIBRARY_NAME "!" __FUNCTION__ ": " fmt "\n", SD)
+#define DEBUGLOGSID(fmt, Sid) \
+ FspDebugLogSid("[U] " LIBRARY_NAME "!" __FUNCTION__ ": " fmt "\n", Sid)
#else
#define DEBUGLOG(fmt, ...) ((void)0)
#define DEBUGLOGSD(fmt, SD) ((void)0)
+#define DEBUGLOGSID(fmt, Sid) ((void)0)
#endif
+VOID FspWksidFinalize(BOOLEAN Dynamic);
VOID FspPosixFinalize(BOOLEAN Dynamic);
VOID FspEventLogFinalize(BOOLEAN Dynamic);
VOID FspServiceFinalize(BOOLEAN Dynamic);
@@ -49,6 +53,9 @@ NTSTATUS FspNpUnregister(VOID);
NTSTATUS FspEventLogRegister(VOID);
NTSTATUS FspEventLogUnregister(VOID);
+PSID FspWksidNew(WELL_KNOWN_SID_TYPE WellKnownSidType, PNTSTATUS PResult);
+PSID FspWksidGet(WELL_KNOWN_SID_TYPE WellKnownSidType);
+
PWSTR FspDiagIdent(VOID);
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
diff --git a/src/dll/posix.c b/src/dll/posix.c
index 5640115c..ef566e18 100644
--- a/src/dll/posix.c
+++ b/src/dll/posix.c
@@ -453,9 +453,12 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
if (!NT_SUCCESS(Result))
goto exit;
- Result = FspPosixMapUidToSid(0x10100, &WorldSid);
- if (!NT_SUCCESS(Result))
+ WorldSid = FspWksidGet(WinWorldSid);
+ if (0 == WorldSid)
+ {
+ Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
+ }
OwnerPerm = (Mode & 0700) >> 6;
GroupPerm = (Mode & 0070) >> 3;
@@ -579,9 +582,6 @@ exit:
MemFree(Acl);
- if (0 != WorldSid)
- FspDeleteSid(WorldSid, FspPosixMapUidToSid);
-
if (0 != GroupSid)
FspDeleteSid(GroupSid, FspPosixMapUidToSid);
@@ -649,13 +649,19 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
if (0 != Acl)
{
- Result = FspPosixMapUidToSid(0x10100, &WorldSid);
- if (!NT_SUCCESS(Result))
+ WorldSid = FspWksidGet(WinWorldSid);
+ if (0 == WorldSid)
+ {
+ Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
+ }
- Result = FspPosixMapUidToSid(11, &AuthUsersSid);
- if (!NT_SUCCESS(Result))
+ AuthUsersSid = FspWksidGet(WinAuthenticatedUserSid);
+ if (0 == AuthUsersSid)
+ {
+ Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
+ }
OwnerAllow = OwnerDeny = GroupAllow = GroupDeny = WorldAllow = WorldDeny = 0;
@@ -771,12 +777,6 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
Result = STATUS_SUCCESS;
exit:
- if (0 != AuthUsersSid)
- FspDeleteSid(AuthUsersSid, FspPosixMapUidToSid);
-
- if (0 != WorldSid)
- FspDeleteSid(WorldSid, FspPosixMapUidToSid);
-
return Result;
lasterror:
diff --git a/src/dll/util.c b/src/dll/util.c
index cd36df5c..27746351 100644
--- a/src/dll/util.c
+++ b/src/dll/util.c
@@ -97,24 +97,14 @@ FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName,
{
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
PSID OwnerSid, WellKnownSid = 0;
- DWORD SidSize, LastError;
+ DWORD LastError;
/* if it is a small number treat it like a well known SID */
if (1024 > (INT_PTR)Sid)
{
- SidSize = SECURITY_MAX_SID_SIZE;
- WellKnownSid = MemAlloc(SidSize);
+ WellKnownSid = FspWksidNew((INT_PTR)Sid, &Result);
if (0 == WellKnownSid)
- {
- Result = STATUS_INSUFFICIENT_RESOURCES;
goto sid_exit;
- }
-
- if (!CreateWellKnownSid((INT_PTR)Sid, 0, WellKnownSid, &SidSize))
- {
- Result = FspNtStatusFromWin32(GetLastError());
- goto sid_exit;
- }
}
LastError = GetSecurityInfo(Pipe, SE_FILE_OBJECT,
diff --git a/src/dll/wksid.c b/src/dll/wksid.c
new file mode 100644
index 00000000..4617fcde
--- /dev/null
+++ b/src/dll/wksid.c
@@ -0,0 +1,114 @@
+/**
+ * @file dll/wksid.c
+ *
+ * @copyright 2015-2017 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 file in
+ * accordance with the commercial license agreement provided with the
+ * software.
+ */
+
+#include
+
+static INIT_ONCE FspWksidInitOnce = INIT_ONCE_STATIC_INIT;
+static PSID FspWksidWorld;
+static PSID FspWksidAuthenticatedUser;
+static PSID FspWksidLocalSystem;
+static PSID FspWksidLocalService;
+static PSID FspWksidNetworkService;
+
+static BOOL WINAPI FspWksidInitialize(
+ PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
+{
+ FspWksidWorld = FspWksidNew(WinWorldSid, 0);
+ FspWksidAuthenticatedUser = FspWksidNew(WinAuthenticatedUserSid, 0);
+ FspWksidLocalSystem = FspWksidNew(WinLocalSystemSid, 0);
+ FspWksidLocalService = FspWksidNew(WinLocalServiceSid, 0);
+ FspWksidNetworkService = FspWksidNew(WinNetworkServiceSid, 0);
+
+ //DEBUGLOGSID("FspWksidWorld=%s", FspWksidWorld);
+ //DEBUGLOGSID("FspWksidAuthenticatedUser=%s", FspWksidAuthenticatedUser);
+ //DEBUGLOGSID("FspWksidLocalSystem=%s", FspWksidLocalSystem);
+ //DEBUGLOGSID("FspWksidLocalService=%s", FspWksidLocalService);
+ //DEBUGLOGSID("FspWksidNetworkService=%s", FspWksidNetworkService);
+
+ return TRUE;
+}
+
+VOID FspWksidFinalize(BOOLEAN Dynamic)
+{
+ /*
+ * This function is called during DLL_PROCESS_DETACH. We must therefore keep
+ * finalization tasks to a minimum.
+ *
+ * We must deregister our event source (if any). We only do so if the library
+ * is being explicitly unloaded (rather than the process exiting).
+ */
+
+ if (Dynamic)
+ {
+ MemFree(FspWksidWorld); FspWksidWorld = 0;
+ MemFree(FspWksidAuthenticatedUser); FspWksidAuthenticatedUser = 0;
+ MemFree(FspWksidLocalSystem); FspWksidLocalSystem = 0;
+ MemFree(FspWksidLocalService); FspWksidLocalService = 0;
+ MemFree(FspWksidNetworkService); FspWksidNetworkService = 0;
+ }
+}
+
+PSID FspWksidNew(WELL_KNOWN_SID_TYPE WellKnownSidType, PNTSTATUS PResult)
+{
+ NTSTATUS Result;
+ PSID Sid;
+ DWORD Size;
+
+ Size = SECURITY_MAX_SID_SIZE;
+ Sid = MemAlloc(Size);
+ if (0 == Sid)
+ {
+ Result = STATUS_INSUFFICIENT_RESOURCES;
+ goto exit;
+ }
+
+ if (!CreateWellKnownSid(WellKnownSidType, 0, Sid, &Size))
+ {
+ Result = FspNtStatusFromWin32(GetLastError());
+ MemFree(Sid); Sid = 0;
+ goto exit;
+ }
+
+ Result = STATUS_SUCCESS;
+
+exit:
+ if (0 != PResult)
+ *PResult = Result;
+
+ return Sid;
+}
+
+PSID FspWksidGet(WELL_KNOWN_SID_TYPE WellKnownSidType)
+{
+ InitOnceExecuteOnce(&FspWksidInitOnce, FspWksidInitialize, 0, 0);
+
+ switch (WellKnownSidType)
+ {
+ case WinWorldSid:
+ return FspWksidWorld;
+ case WinAuthenticatedUserSid:
+ return FspWksidAuthenticatedUser;
+ case WinLocalSystemSid:
+ return FspWksidLocalSystem;
+ case WinLocalServiceSid:
+ return FspWksidLocalService;
+ case WinNetworkServiceSid:
+ return FspWksidNetworkService;
+ default:
+ return 0;
+ }
+}