mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
launcher: can now perform DefineDosDevice in LocalSystem context
dll: uses launcher to DefineDosDevice for LocalService, etc.
This commit is contained in:
parent
5d3b37122c
commit
ff155694ce
@ -1675,6 +1675,19 @@ FSP_API VOID FspServiceStop(FSP_SERVICE *Service);
|
|||||||
* TRUE if the process is running in running user interactive mode.
|
* TRUE if the process is running in running user interactive mode.
|
||||||
*/
|
*/
|
||||||
FSP_API BOOLEAN FspServiceIsInteractive(VOID);
|
FSP_API BOOLEAN FspServiceIsInteractive(VOID);
|
||||||
|
/**
|
||||||
|
* Check if the supplied token is from the service context.
|
||||||
|
*
|
||||||
|
* @param Token
|
||||||
|
* Token to check. Pass NULL to check the current process token.
|
||||||
|
* @param PIsLocalSystem
|
||||||
|
* Pointer to a boolean that will receive a TRUE value if the token belongs to LocalSystem
|
||||||
|
* and FALSE otherwise. May be NULL.
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS if the token is from the service context. STATUS_ACCESS_DENIED if it is not.
|
||||||
|
* Other error codes are possible.
|
||||||
|
*/
|
||||||
|
FSP_API NTSTATUS FspServiceContextCheck(HANDLE Token, PBOOLEAN PIsLocalSystem);
|
||||||
/**
|
/**
|
||||||
* Log a service message.
|
* Log a service message.
|
||||||
*
|
*
|
||||||
|
112
src/dll/fs.c
112
src/dll/fs.c
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dll/library.h>
|
#include <dll/library.h>
|
||||||
|
#include <launcher/launcher.h>
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -187,17 +188,101 @@ FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem)
|
|||||||
MemFree(FileSystem);
|
MemFree(FileSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFileSystemLauncherDefineDosDevice(
|
||||||
|
WCHAR Sign, PWSTR MountPoint, PWSTR VolumeName)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
ULONG MountPointLen, VolumeNameLen;
|
||||||
|
PWSTR PipeBuf = 0, P;
|
||||||
|
DWORD BytesTransferred;
|
||||||
|
|
||||||
|
MountPointLen = lstrlenW(MountPoint);
|
||||||
|
VolumeNameLen = lstrlenW(VolumeName);
|
||||||
|
|
||||||
|
if (2 != MountPointLen ||
|
||||||
|
FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR) <= VolumeNameLen)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE);
|
||||||
|
if (0 == PipeBuf)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
P = PipeBuf;
|
||||||
|
*P++ = LauncherDefineDosDevice;
|
||||||
|
*P++ = Sign;
|
||||||
|
memcpy(P, MountPoint, MountPointLen * sizeof(WCHAR)); P += MountPointLen; *P++ = L'\0';
|
||||||
|
memcpy(P, VolumeName, VolumeNameLen * sizeof(WCHAR)); P += VolumeNameLen; *P++ = L'\0';
|
||||||
|
|
||||||
|
Result = FspCallNamedPipeSecurely(L"" LAUNCHER_PIPE_NAME,
|
||||||
|
PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE,
|
||||||
|
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, LAUNCHER_PIPE_OWNER);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if (sizeof(WCHAR) > BytesTransferred)
|
||||||
|
Result = RPC_NT_PROTOCOL_ERROR;
|
||||||
|
else if (LauncherSuccess == PipeBuf[0])
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
else if (LauncherFailure == PipeBuf[0])
|
||||||
|
{
|
||||||
|
DWORD ErrorCode = 0;
|
||||||
|
|
||||||
|
for (PWSTR P = PipeBuf + 1, EndP = PipeBuf + BytesTransferred / sizeof(WCHAR); EndP > P; P++)
|
||||||
|
{
|
||||||
|
if (L'0' > *P || *P > L'9')
|
||||||
|
break;
|
||||||
|
|
||||||
|
ErrorCode = 10 * ErrorCode + (*P - L'0');
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = FspNtStatusFromWin32(ErrorCode);
|
||||||
|
if (0 == Result)
|
||||||
|
Result = RPC_NT_PROTOCOL_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result = RPC_NT_PROTOCOL_ERROR;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(PipeBuf);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFileSystemSetMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName,
|
static NTSTATUS FspFileSystemSetMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName,
|
||||||
PHANDLE PMountHandle)
|
PHANDLE PMountHandle)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
BOOLEAN IsLocalSystem, IsServiceContext;
|
||||||
|
|
||||||
*PMountHandle = 0;
|
*PMountHandle = 0;
|
||||||
|
|
||||||
if (!DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, VolumeName))
|
Result = FspServiceContextCheck(0, &IsLocalSystem);
|
||||||
return FspNtStatusFromWin32(GetLastError());
|
IsServiceContext = NT_SUCCESS(Result) && !IsLocalSystem;
|
||||||
|
if (IsServiceContext)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If the current process is in the service context but not LocalSystem,
|
||||||
|
* ask the launcher to DefineDosDevice for us. This is because the launcher
|
||||||
|
* runs in the LocalSystem context and can create global drives.
|
||||||
|
*
|
||||||
|
* In this case the launcher will also add DELETE access to the drive symlink
|
||||||
|
* for us, so that we can make it temporary below.
|
||||||
|
*/
|
||||||
|
Result = FspFileSystemLauncherDefineDosDevice(L'+', MountPoint, VolumeName);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, VolumeName))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
if (0 != FspNtOpenSymbolicLinkObject)
|
if (0 != FspNtOpenSymbolicLinkObject)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
|
||||||
WCHAR SymlinkBuf[6];
|
WCHAR SymlinkBuf[6];
|
||||||
UNICODE_STRING Symlink;
|
UNICODE_STRING Symlink;
|
||||||
OBJECT_ATTRIBUTES Obja;
|
OBJECT_ATTRIBUTES Obja;
|
||||||
@ -224,6 +309,13 @@ static NTSTATUS FspFileSystemSetMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HACK:
|
||||||
|
*
|
||||||
|
* Handles do not use the low 2 bits (unless they are console handles).
|
||||||
|
* Abuse this fact to remember that we are running in the service context.
|
||||||
|
*/
|
||||||
|
*PMountHandle = (HANDLE)(UINT_PTR)((DWORD)(UINT_PTR)*PMountHandle | IsServiceContext);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,8 +503,18 @@ exit:
|
|||||||
|
|
||||||
static VOID FspFileSystemRemoveMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName, HANDLE MountHandle)
|
static VOID FspFileSystemRemoveMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName, HANDLE MountHandle)
|
||||||
{
|
{
|
||||||
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
BOOLEAN IsServiceContext = 0 != ((DWORD)(UINT_PTR)MountHandle & 1);
|
||||||
MountPoint, VolumeName);
|
MountHandle = (HANDLE)(UINT_PTR)((DWORD)(UINT_PTR)MountHandle & ~1);
|
||||||
|
if (IsServiceContext)
|
||||||
|
/*
|
||||||
|
* If the current process is in the service context but not LocalSystem,
|
||||||
|
* ask the launcher to DefineDosDevice for us. This is because the launcher
|
||||||
|
* runs in the LocalSystem context and can remove global drives.
|
||||||
|
*/
|
||||||
|
FspFileSystemLauncherDefineDosDevice(L'-', MountPoint, VolumeName);
|
||||||
|
else
|
||||||
|
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
||||||
|
MountPoint, VolumeName);
|
||||||
|
|
||||||
if (0 != MountHandle)
|
if (0 != MountHandle)
|
||||||
FspNtClose(MountHandle);
|
FspNtClose(MountHandle);
|
||||||
|
@ -566,6 +566,106 @@ FSP_API BOOLEAN FspServiceIsInteractive(VOID)
|
|||||||
return IsInteractive;
|
return IsInteractive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspServiceContextCheck(HANDLE Token, PBOOLEAN PIsLocalSystem)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
PSID LocalSystemSid, ServiceSid;
|
||||||
|
BOOLEAN IsLocalSystem = FALSE;
|
||||||
|
BOOL HasServiceSid = FALSE;
|
||||||
|
HANDLE ProcessToken = 0, ImpersonationToken = 0;
|
||||||
|
DWORD SessionId, Size;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
TOKEN_USER V;
|
||||||
|
UINT8 B[128];
|
||||||
|
} UserInfoBuf;
|
||||||
|
PTOKEN_USER UserInfo = &UserInfoBuf.V;
|
||||||
|
|
||||||
|
LocalSystemSid = FspWksidGet(WinLocalSystemSid);
|
||||||
|
ServiceSid = FspWksidGet(WinServiceSid);
|
||||||
|
if (0 == LocalSystemSid || 0 == ServiceSid)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == Token)
|
||||||
|
{
|
||||||
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &ProcessToken) ||
|
||||||
|
!DuplicateToken(ProcessToken, SecurityImpersonation, &ImpersonationToken))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token = ImpersonationToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenSessionId, &SessionId, sizeof SessionId, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != SessionId)
|
||||||
|
{
|
||||||
|
Result = STATUS_ACCESS_DENIED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, UserInfo, sizeof UserInfoBuf, &Size))
|
||||||
|
{
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserInfo = MemAlloc(Size);
|
||||||
|
if (0 == UserInfo)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, UserInfo, Size, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IsLocalSystem = EqualSid(LocalSystemSid, UserInfo->User.Sid);
|
||||||
|
if (IsLocalSystem)
|
||||||
|
{
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CheckTokenMembership(Token, ServiceSid, &HasServiceSid))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = HasServiceSid ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (0 != PIsLocalSystem)
|
||||||
|
*PIsLocalSystem = NT_SUCCESS(Result) ? IsLocalSystem : FALSE;
|
||||||
|
|
||||||
|
if (UserInfo != &UserInfoBuf.V)
|
||||||
|
MemFree(UserInfo);
|
||||||
|
|
||||||
|
if (0 != ImpersonationToken)
|
||||||
|
CloseHandle(ImpersonationToken);
|
||||||
|
|
||||||
|
if (0 != ProcessToken)
|
||||||
|
CloseHandle(ProcessToken);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API VOID FspServiceLog(ULONG Type, PWSTR Format, ...)
|
FSP_API VOID FspServiceLog(ULONG Type, PWSTR Format, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -21,8 +21,7 @@ static INIT_ONCE FspWksidInitOnce = INIT_ONCE_STATIC_INIT;
|
|||||||
static PSID FspWksidWorld;
|
static PSID FspWksidWorld;
|
||||||
static PSID FspWksidAuthenticatedUser;
|
static PSID FspWksidAuthenticatedUser;
|
||||||
static PSID FspWksidLocalSystem;
|
static PSID FspWksidLocalSystem;
|
||||||
static PSID FspWksidLocalService;
|
static PSID FspWksidService;
|
||||||
static PSID FspWksidNetworkService;
|
|
||||||
|
|
||||||
static BOOL WINAPI FspWksidInitialize(
|
static BOOL WINAPI FspWksidInitialize(
|
||||||
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
|
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
|
||||||
@ -30,14 +29,12 @@ static BOOL WINAPI FspWksidInitialize(
|
|||||||
FspWksidWorld = FspWksidNew(WinWorldSid, 0);
|
FspWksidWorld = FspWksidNew(WinWorldSid, 0);
|
||||||
FspWksidAuthenticatedUser = FspWksidNew(WinAuthenticatedUserSid, 0);
|
FspWksidAuthenticatedUser = FspWksidNew(WinAuthenticatedUserSid, 0);
|
||||||
FspWksidLocalSystem = FspWksidNew(WinLocalSystemSid, 0);
|
FspWksidLocalSystem = FspWksidNew(WinLocalSystemSid, 0);
|
||||||
FspWksidLocalService = FspWksidNew(WinLocalServiceSid, 0);
|
FspWksidService = FspWksidNew(WinServiceSid, 0);
|
||||||
FspWksidNetworkService = FspWksidNew(WinNetworkServiceSid, 0);
|
|
||||||
|
|
||||||
//DEBUGLOGSID("FspWksidWorld=%s", FspWksidWorld);
|
//DEBUGLOGSID("FspWksidWorld=%s", FspWksidWorld);
|
||||||
//DEBUGLOGSID("FspWksidAuthenticatedUser=%s", FspWksidAuthenticatedUser);
|
//DEBUGLOGSID("FspWksidAuthenticatedUser=%s", FspWksidAuthenticatedUser);
|
||||||
//DEBUGLOGSID("FspWksidLocalSystem=%s", FspWksidLocalSystem);
|
//DEBUGLOGSID("FspWksidLocalSystem=%s", FspWksidLocalSystem);
|
||||||
//DEBUGLOGSID("FspWksidLocalService=%s", FspWksidLocalService);
|
//DEBUGLOGSID("FspWksidService=%s", FspWksidService);
|
||||||
//DEBUGLOGSID("FspWksidNetworkService=%s", FspWksidNetworkService);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -57,8 +54,7 @@ VOID FspWksidFinalize(BOOLEAN Dynamic)
|
|||||||
MemFree(FspWksidWorld); FspWksidWorld = 0;
|
MemFree(FspWksidWorld); FspWksidWorld = 0;
|
||||||
MemFree(FspWksidAuthenticatedUser); FspWksidAuthenticatedUser = 0;
|
MemFree(FspWksidAuthenticatedUser); FspWksidAuthenticatedUser = 0;
|
||||||
MemFree(FspWksidLocalSystem); FspWksidLocalSystem = 0;
|
MemFree(FspWksidLocalSystem); FspWksidLocalSystem = 0;
|
||||||
MemFree(FspWksidLocalService); FspWksidLocalService = 0;
|
MemFree(FspWksidService); FspWksidService = 0;
|
||||||
MemFree(FspWksidNetworkService); FspWksidNetworkService = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,10 +100,8 @@ PSID FspWksidGet(WELL_KNOWN_SID_TYPE WellKnownSidType)
|
|||||||
return FspWksidAuthenticatedUser;
|
return FspWksidAuthenticatedUser;
|
||||||
case WinLocalSystemSid:
|
case WinLocalSystemSid:
|
||||||
return FspWksidLocalSystem;
|
return FspWksidLocalSystem;
|
||||||
case WinLocalServiceSid:
|
case WinServiceSid:
|
||||||
return FspWksidLocalService;
|
return FspWksidService;
|
||||||
case WinNetworkServiceSid:
|
|
||||||
return FspWksidNetworkService;
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,13 @@
|
|||||||
|
|
||||||
#define PROGNAME "WinFsp.Launcher"
|
#define PROGNAME "WinFsp.Launcher"
|
||||||
|
|
||||||
|
static NTSTATUS (NTAPI *SvcNtOpenSymbolicLinkObject)(
|
||||||
|
PHANDLE LinkHandle,
|
||||||
|
ACCESS_MASK DesiredAccess,
|
||||||
|
POBJECT_ATTRIBUTES ObjectAttributes);
|
||||||
|
static NTSTATUS (NTAPI *SvcNtClose)(
|
||||||
|
HANDLE Handle);
|
||||||
|
|
||||||
BOOL CreateOverlappedPipe(
|
BOOL CreateOverlappedPipe(
|
||||||
PHANDLE PReadPipe, PHANDLE PWritePipe,
|
PHANDLE PReadPipe, PHANDLE PWritePipe,
|
||||||
DWORD Size,
|
DWORD Size,
|
||||||
@ -143,6 +150,96 @@ exit:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS AddAccessForTokenUser(HANDLE Handle, DWORD Access, HANDLE Token)
|
||||||
|
{
|
||||||
|
TOKEN_USER *User = 0;
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
|
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
|
||||||
|
EXPLICIT_ACCESSW AccessEntry;
|
||||||
|
DWORD Size, LastError;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (GetTokenInformation(Token, TokenUser, 0, 0, &Size))
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
User = MemAlloc(Size);
|
||||||
|
if (0 == User)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, User, Size, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetKernelObjectSecurity(Handle, DACL_SECURITY_INFORMATION, 0, 0, &Size))
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
SecurityDescriptor = MemAlloc(Size);
|
||||||
|
if (0 == SecurityDescriptor)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetKernelObjectSecurity(Handle, DACL_SECURITY_INFORMATION, SecurityDescriptor, Size, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessEntry.grfAccessPermissions = Access;
|
||||||
|
AccessEntry.grfAccessMode = GRANT_ACCESS;
|
||||||
|
AccessEntry.grfInheritance = NO_INHERITANCE;
|
||||||
|
AccessEntry.Trustee.pMultipleTrustee = 0;
|
||||||
|
AccessEntry.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
||||||
|
AccessEntry.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||||
|
AccessEntry.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
|
||||||
|
AccessEntry.Trustee.ptstrName = User->User.Sid;
|
||||||
|
|
||||||
|
LastError = BuildSecurityDescriptorW(0, 0, 1, &AccessEntry, 0, 0, SecurityDescriptor,
|
||||||
|
&Size, &NewSecurityDescriptor);
|
||||||
|
if (0 != LastError)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(LastError);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SetKernelObjectSecurity(Handle, DACL_SECURITY_INFORMATION, NewSecurityDescriptor))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
LocalFree(NewSecurityDescriptor);
|
||||||
|
MemFree(SecurityDescriptor);
|
||||||
|
MemFree(User);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL LogonCreateProcess(
|
static BOOL LogonCreateProcess(
|
||||||
PWSTR UserName,
|
PWSTR UserName,
|
||||||
LPCWSTR ApplicationName,
|
LPCWSTR ApplicationName,
|
||||||
@ -1206,6 +1303,53 @@ NTSTATUS SvcInstanceStopAndWaitAll(VOID)
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS SvcDefineDosDevice(HANDLE ClientToken,
|
||||||
|
PWSTR DeviceName, PWSTR TargetPath)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (L'+' != DeviceName[0] && L'-' != DeviceName[0])
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
Result = FspServiceContextCheck(ClientToken, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
if (!DefineDosDeviceW(
|
||||||
|
DDD_RAW_TARGET_PATH |
|
||||||
|
(L'+' == DeviceName[0] ? 0 : DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE),
|
||||||
|
DeviceName + 1, TargetPath))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
if (L'+' == DeviceName[0] && 0 != SvcNtOpenSymbolicLinkObject)
|
||||||
|
{
|
||||||
|
/* The drive symlink now exists; add DELETE access to it for the ClientToken. */
|
||||||
|
WCHAR SymlinkBuf[6];
|
||||||
|
UNICODE_STRING Symlink;
|
||||||
|
OBJECT_ATTRIBUTES Obja;
|
||||||
|
HANDLE MountHandle;
|
||||||
|
|
||||||
|
memcpy(SymlinkBuf, L"\\??\\X:", sizeof SymlinkBuf);
|
||||||
|
SymlinkBuf[4] = DeviceName[1];
|
||||||
|
Symlink.Length = Symlink.MaximumLength = sizeof SymlinkBuf;
|
||||||
|
Symlink.Buffer = SymlinkBuf;
|
||||||
|
|
||||||
|
memset(&Obja, 0, sizeof Obja);
|
||||||
|
Obja.Length = sizeof Obja;
|
||||||
|
Obja.ObjectName = &Symlink;
|
||||||
|
Obja.Attributes = OBJ_CASE_INSENSITIVE;
|
||||||
|
|
||||||
|
Result = SvcNtOpenSymbolicLinkObject(&MountHandle, READ_CONTROL | WRITE_DAC, &Obja);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
AddAccessForTokenUser(MountHandle, DELETE, ClientToken);
|
||||||
|
SvcNtClose(MountHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static HANDLE SvcJob, SvcThread, SvcEvent;
|
static HANDLE SvcJob, SvcThread, SvcEvent;
|
||||||
static DWORD SvcThreadId;
|
static DWORD SvcThreadId;
|
||||||
static HANDLE SvcPipe = INVALID_HANDLE_VALUE;
|
static HANDLE SvcPipe = INVALID_HANDLE_VALUE;
|
||||||
@ -1526,6 +1670,7 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
|||||||
|
|
||||||
PWSTR P = PipeBuf, PipeBufEnd = PipeBuf + *PSize / sizeof(WCHAR);
|
PWSTR P = PipeBuf, PipeBufEnd = PipeBuf + *PSize / sizeof(WCHAR);
|
||||||
PWSTR ClassName, InstanceName, UserName;
|
PWSTR ClassName, InstanceName, UserName;
|
||||||
|
PWSTR DeviceName, TargetPath;
|
||||||
ULONG Argc; PWSTR Argv[9];
|
ULONG Argc; PWSTR Argv[9];
|
||||||
BOOLEAN HasSecret = FALSE;
|
BOOLEAN HasSecret = FALSE;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
@ -1587,6 +1732,17 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
|||||||
SvcPipeTransactResult(Result, PipeBuf, PSize);
|
SvcPipeTransactResult(Result, PipeBuf, PSize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LauncherDefineDosDevice:
|
||||||
|
DeviceName = SvcPipeTransactGetPart(&P, PipeBufEnd);
|
||||||
|
TargetPath = SvcPipeTransactGetPart(&P, PipeBufEnd);
|
||||||
|
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
if (0 != DeviceName && 0 != TargetPath)
|
||||||
|
Result = SvcDefineDosDevice(ClientToken, DeviceName, TargetPath);
|
||||||
|
|
||||||
|
SvcPipeTransactResult(Result, PipeBuf, PSize);
|
||||||
|
break;
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
case LauncherQuit:
|
case LauncherQuit:
|
||||||
SetEvent(SvcEvent);
|
SetEvent(SvcEvent);
|
||||||
@ -1605,6 +1761,19 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
|||||||
|
|
||||||
int wmain(int argc, wchar_t **argv)
|
int wmain(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
|
HANDLE Handle = GetModuleHandleW(L"ntdll.dll");
|
||||||
|
if (0 != Handle)
|
||||||
|
{
|
||||||
|
SvcNtOpenSymbolicLinkObject = (PVOID)GetProcAddress(Handle, "NtOpenSymbolicLinkObject");
|
||||||
|
SvcNtClose = (PVOID)GetProcAddress(Handle, "NtClose");
|
||||||
|
|
||||||
|
if (0 == SvcNtOpenSymbolicLinkObject || 0 == SvcNtClose)
|
||||||
|
{
|
||||||
|
SvcNtOpenSymbolicLinkObject = 0;
|
||||||
|
SvcNtClose = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FspServiceRun(L"" PROGNAME, SvcStart, SvcStop, 0);
|
return FspServiceRun(L"" PROGNAME, SvcStart, SvcStop, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#define LAUNCHER_PIPE_NAME "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}"
|
#define LAUNCHER_PIPE_NAME "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}"
|
||||||
#define LAUNCHER_PIPE_BUFFER_SIZE 4096
|
#define LAUNCHER_PIPE_BUFFER_SIZE 4096
|
||||||
#define LAUNCHER_PIPE_DEFAULT_TIMEOUT 3000
|
#define LAUNCHER_PIPE_DEFAULT_TIMEOUT (2 * 15000 + 1000)
|
||||||
|
|
||||||
#define LAUNCHER_START_WITH_SECRET_TIMEOUT 15000
|
#define LAUNCHER_START_WITH_SECRET_TIMEOUT 15000
|
||||||
|
|
||||||
@ -62,6 +62,7 @@ enum
|
|||||||
LauncherSvcInstanceStop = 'T', /* requires: SERVICE_STOP */
|
LauncherSvcInstanceStop = 'T', /* requires: SERVICE_STOP */
|
||||||
LauncherSvcInstanceInfo = 'I', /* requires: SERVICE_QUERY_STATUS */
|
LauncherSvcInstanceInfo = 'I', /* requires: SERVICE_QUERY_STATUS */
|
||||||
LauncherSvcInstanceList = 'L', /* requires: none*/
|
LauncherSvcInstanceList = 'L', /* requires: none*/
|
||||||
|
LauncherDefineDosDevice = 'D',
|
||||||
LauncherQuit = 'Q', /* DEBUG version only */
|
LauncherQuit = 'Q', /* DEBUG version only */
|
||||||
|
|
||||||
LauncherSuccess = '$',
|
LauncherSuccess = '$',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user