From 4fe85222b12af8f57ea5fa9dbff2ac97d4148c4f Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Mon, 11 Dec 2017 15:03:32 -0800 Subject: [PATCH] dll: wksid: well known SID's --- build/VStudio/winfsp_dll.vcxproj | 1 + build/VStudio/winfsp_dll.vcxproj.filters | 3 + inc/winfsp/winfsp.h | 1 + src/dll/debug.c | 15 +++ src/dll/fsctl.c | 11 +-- src/dll/library.c | 1 + src/dll/library.h | 7 ++ src/dll/posix.c | 30 +++--- src/dll/util.c | 14 +-- src/dll/wksid.c | 114 +++++++++++++++++++++++ 10 files changed, 161 insertions(+), 36 deletions(-) create mode 100644 src/dll/wksid.c 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; + } +}