dll: FspFileSystemRegister: fix WinFsp service security descriptor to allow Everyone to start the service

This commit is contained in:
Bill Zissimopoulos 2016-05-04 13:29:34 -07:00
parent ff0b8bc3fe
commit b1b31b9017

View File

@ -16,6 +16,7 @@
*/ */
#include <dll/library.h> #include <dll/library.h>
#include <aclapi.h>
enum enum
{ {
@ -373,6 +374,119 @@ FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
} }
} }
static NTSTATUS FspFileSystemFixServiceSecurity(HANDLE SvcHandle)
{
/*
* This function adds an ACE that allows Everyone to start a service.
*/
PSID WorldSid = 0;
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
EXPLICIT_ACCESSW AccessEntry;
ACCESS_MASK AccessRights;
PACL Dacl;
BOOL DaclPresent, DaclDefaulted;
DWORD Size;
DWORD LastError;
NTSTATUS Result;
/* get the Everyone (World) SID */
Size = SECURITY_MAX_SID_SIZE;
WorldSid = MemAlloc(Size);
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;
if (!QueryServiceObjectSecurity(SvcHandle, DACL_SECURITY_INFORMATION, SecurityDescriptor, Size, &Size))
{
LastError = GetLastError();
if (ERROR_INSUFFICIENT_BUFFER != LastError)
{
Result = FspNtStatusFromWin32(LastError);
goto exit;
}
}
SecurityDescriptor = MemAlloc(Size);
if (0 == SecurityDescriptor)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
if (!QueryServiceObjectSecurity(SvcHandle, DACL_SECURITY_INFORMATION, SecurityDescriptor, Size, &Size))
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
/* extract the DACL */
if (!GetSecurityDescriptorDacl(SecurityDescriptor, &DaclPresent, &Dacl, &DaclDefaulted))
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
/* prepare an EXPLICIT_ACCESS for the SERVICE_START right for Everyone */
AccessEntry.grfAccessPermissions = SERVICE_START;
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 = WorldSid;
/* get the effective rights for Everyone */
AccessRights = 0;
if (DaclPresent && 0 != Dacl)
{
LastError = GetEffectiveRightsFromAclW(Dacl, &AccessEntry.Trustee, &AccessRights);
if (0 != LastError)
{
Result = FspNtStatusFromWin32(LastError);
goto exit;
}
}
/* do we have the required access rights? */
if (AccessEntry.grfAccessPermissions != (AccessRights & AccessEntry.grfAccessPermissions))
{
/* create a new security descriptor with the new access */
LastError = BuildSecurityDescriptorW(0, 0, 1, &AccessEntry, 0, 0, SecurityDescriptor,
&Size, &NewSecurityDescriptor);
if (0 != LastError)
{
Result = FspNtStatusFromWin32(LastError);
goto exit;
}
/* set the new service security descriptor DACL */
if (!SetServiceObjectSecurity(SvcHandle, DACL_SECURITY_INFORMATION, NewSecurityDescriptor))
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
}
Result = STATUS_SUCCESS;
exit:
LocalFree(NewSecurityDescriptor);
MemFree(SecurityDescriptor);
MemFree(WorldSid);
return Result;
}
NTSTATUS FspFileSystemRegister(VOID) NTSTATUS FspFileSystemRegister(VOID)
{ {
extern HINSTANCE DllInstance; extern HINSTANCE DllInstance;
@ -411,20 +525,28 @@ NTSTATUS FspFileSystemRegister(VOID)
goto exit; goto exit;
} }
SvcHandle = OpenServiceW(ScmHandle, DriverName, SERVICE_CHANGE_CONFIG); SvcHandle = OpenServiceW(ScmHandle, DriverName, SERVICE_CHANGE_CONFIG | READ_CONTROL | WRITE_DAC);
if (0 != SvcHandle) if (0 != SvcHandle)
ChangeServiceConfigW(SvcHandle, {
if (!ChangeServiceConfigW(SvcHandle,
SERVICE_FILE_SYSTEM_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, DriverPath, SERVICE_FILE_SYSTEM_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, DriverPath,
0, 0, 0, 0, 0, DriverName); 0, 0, 0, 0, 0, DriverName))
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
}
else else
{
SvcHandle = CreateServiceW(ScmHandle, DriverName, DriverName, SvcHandle = CreateServiceW(ScmHandle, DriverName, DriverName,
SERVICE_CHANGE_CONFIG, SERVICE_CHANGE_CONFIG | READ_CONTROL | WRITE_DAC,
SERVICE_FILE_SYSTEM_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, DriverPath, SERVICE_FILE_SYSTEM_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, DriverPath,
0, 0, 0, 0, 0); 0, 0, 0, 0, 0);
if (0 == SvcHandle) if (0 == SvcHandle)
{ {
Result = FspNtStatusFromWin32(GetLastError()); Result = FspNtStatusFromWin32(GetLastError());
goto exit; goto exit;
}
} }
Size = GetFileVersionInfoSizeW(DriverPath, &Size/*dummy*/); Size = GetFileVersionInfoSizeW(DriverPath, &Size/*dummy*/);
@ -440,6 +562,10 @@ NTSTATUS FspFileSystemRegister(VOID)
} }
} }
Result = FspFileSystemFixServiceSecurity(SvcHandle);
if (!NT_SUCCESS(Result))
goto exit;
Result = STATUS_SUCCESS; Result = STATUS_SUCCESS;
exit: exit: