mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
dll: FspCallNamedPipeSecurely replaces CallNamedPipeW
This commit is contained in:
parent
fea92c4ae0
commit
f7adbaba92
@ -183,6 +183,11 @@
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\winfsp_dll.vcxproj">
|
||||
<Project>{4a7c0b21-9e10-4c81-92de-1493efcf24eb}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@ -1034,6 +1034,10 @@ FSP_API VOID FspEventLogV(ULONG Type, PWSTR Format, va_list ap);
|
||||
FSP_API VOID FspDebugLog(const char *format, ...);
|
||||
FSP_API VOID FspDebugLogSD(const char *format, PSECURITY_DESCRIPTOR SecurityDescriptor);
|
||||
FSP_API VOID FspDebugLogFT(const char *format, PFILETIME FileTime);
|
||||
FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName,
|
||||
PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize,
|
||||
PULONG PBytesTransferred, ULONG Timeout,
|
||||
PSID Sid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
115
src/dll/np.c
115
src/dll/np.c
@ -17,11 +17,117 @@
|
||||
|
||||
#include <dll/library.h>
|
||||
#include <launcher/launcher.h>
|
||||
#include <aclapi.h>
|
||||
#include <npapi.h>
|
||||
|
||||
#define FSP_NP_NAME LIBRARY_NAME ".Np"
|
||||
#define FSP_NP_TYPE ' spF' /* pick a value hopefully not in use */
|
||||
|
||||
FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName,
|
||||
PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize,
|
||||
PULONG PBytesTransferred, ULONG Timeout,
|
||||
PSID Sid)
|
||||
{
|
||||
NTSTATUS Result;
|
||||
HANDLE Pipe = INVALID_HANDLE_VALUE;
|
||||
DWORD PipeMode;
|
||||
|
||||
Pipe = CreateFileW(PipeName,
|
||||
GENERIC_READ | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
|
||||
SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, 0);
|
||||
if (INVALID_HANDLE_VALUE == Pipe)
|
||||
{
|
||||
if (ERROR_PIPE_BUSY != GetLastError())
|
||||
{
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
goto exit;
|
||||
}
|
||||
|
||||
WaitNamedPipeW(PipeName, Timeout);
|
||||
|
||||
Pipe = CreateFileW(PipeName,
|
||||
GENERIC_READ | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
|
||||
SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, 0);
|
||||
if (INVALID_HANDLE_VALUE == Pipe)
|
||||
{
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != Sid)
|
||||
{
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||
PSID OwnerSid, WellKnownSid = 0;
|
||||
DWORD SidSize, 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);
|
||||
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,
|
||||
OWNER_SECURITY_INFORMATION, &OwnerSid, 0, 0, 0, &SecurityDescriptor);
|
||||
if (0 != LastError)
|
||||
{
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
goto sid_exit;
|
||||
}
|
||||
|
||||
if (!EqualSid(OwnerSid, WellKnownSid ? WellKnownSid : Sid))
|
||||
{
|
||||
Result = STATUS_ACCESS_DENIED;
|
||||
goto sid_exit;
|
||||
}
|
||||
|
||||
Result = STATUS_SUCCESS;
|
||||
|
||||
sid_exit:
|
||||
MemFree(WellKnownSid);
|
||||
LocalFree(SecurityDescriptor);
|
||||
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
}
|
||||
|
||||
PipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT;
|
||||
if (!SetNamedPipeHandleState(Pipe, &PipeMode, 0, 0))
|
||||
{
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!TransactNamedPipe(Pipe, InBuffer, InBufferSize, OutBuffer, OutBufferSize,
|
||||
PBytesTransferred, 0))
|
||||
{
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
goto exit;
|
||||
}
|
||||
|
||||
Result = STATUS_SUCCESS;
|
||||
|
||||
exit:
|
||||
if (INVALID_HANDLE_VALUE != Pipe)
|
||||
CloseHandle(Pipe);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
DWORD APIENTRY NPGetCaps(DWORD Index)
|
||||
{
|
||||
switch (Index)
|
||||
@ -132,12 +238,13 @@ static inline BOOLEAN FspNpParseRemoteName(PWSTR RemoteName,
|
||||
static inline DWORD FspNpCallLauncherPipe(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize)
|
||||
{
|
||||
DWORD NpResult;
|
||||
DWORD LastError, BytesTransferred;
|
||||
NTSTATUS Result;
|
||||
DWORD BytesTransferred;
|
||||
|
||||
LastError = CallNamedPipeW(L"" LAUNCHER_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize,
|
||||
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT) ? 0 : GetLastError();
|
||||
Result = FspCallNamedPipeSecurely(L"" LAUNCHER_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize,
|
||||
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, LAUNCHER_PIPE_OWNER);
|
||||
|
||||
if (0 != LastError)
|
||||
if (!NT_SUCCESS(Result))
|
||||
NpResult = WN_NO_NETWORK;
|
||||
else if (sizeof(WCHAR) > BytesTransferred)
|
||||
NpResult = WN_NO_NETWORK;
|
||||
|
@ -63,13 +63,15 @@ static void usage(void)
|
||||
|
||||
static int call_pipe_and_report(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize)
|
||||
{
|
||||
NTSTATUS Result;
|
||||
DWORD LastError, BytesTransferred;
|
||||
|
||||
LastError = CallNamedPipeW(L"" LAUNCHER_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize,
|
||||
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT) ? 0 : GetLastError();
|
||||
Result = FspCallNamedPipeSecurely(L"" LAUNCHER_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize,
|
||||
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, LAUNCHER_PIPE_OWNER);
|
||||
LastError = FspWin32FromNtStatus(Result);
|
||||
|
||||
if (0 != LastError)
|
||||
warn("KO CallNamedPipeW = %ld", LastError);
|
||||
warn("KO CallNamedPipe = %ld", LastError);
|
||||
else if (sizeof(WCHAR) > BytesTransferred)
|
||||
warn("KO launcher: empty buffer");
|
||||
else if (LauncherSuccess == PipeBuf[0])
|
||||
|
@ -29,16 +29,13 @@
|
||||
#define LAUNCHER_PIPE_DEFAULT_TIMEOUT 3000
|
||||
|
||||
/*
|
||||
* The launcher named pipe SDDL gives full access to LocalSystem and Administrators.
|
||||
* It also gives GENERIC_READ and GENERIC_WRITE access to Everyone. This includes the
|
||||
* FILE_CREATE_PIPE_INSTANCE right which should not normally be granted to any process
|
||||
* that is not the pipe server. The reason that the GENERIC_WRITE is required is to allow
|
||||
* clients to use CallNamedPipeW which opens the pipe handle using CreateFileW and the
|
||||
* GENERIC_READ | GENERIC_WRITE access right. The reason that it should be safe to grant
|
||||
* the FILE_CREATE_PIPE_INSTANCE right is that the server creates the named pipe with
|
||||
* MaxInstances == 1 (and therefore no client can create additional instances).
|
||||
* The launcher named pipe SDDL gives full access to LocalSystem and Administrators and
|
||||
* GENERIC_READ and FILE_WRITE_DATA access to Everyone. We are careful not to give the
|
||||
* FILE_CREATE_PIPE_INSTANCE right to Everyone to disallow the creation of additional
|
||||
* pipe instances.
|
||||
*/
|
||||
#define LAUNCHER_PIPE_SDDL "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGW;;;WD)"
|
||||
#define LAUNCHER_PIPE_SDDL "O:SYG:SYD:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRDCCR;;;WD)"
|
||||
#define LAUNCHER_PIPE_OWNER ((PSID)WinLocalSystemSid)
|
||||
|
||||
/*
|
||||
* The default service instance SDDL gives full access to LocalSystem and Administrators.
|
||||
|
Loading…
x
Reference in New Issue
Block a user