mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
dll: FspFsctlFixServiceSecurity: deny SERVICE_STOP to Everyone
Although the FSD can now be unloaded, this can only be done safely via the new FSP_FSCTL_UNLOAD control code. For this reason we disable the ability to stop the FSD via the Service Manager.
This commit is contained in:
parent
9670caa3fe
commit
7e59c2e5a6
@ -617,8 +617,7 @@ static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
|||||||
PSID WorldSid;
|
PSID WorldSid;
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
|
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
|
||||||
EXPLICIT_ACCESSW AccessEntry;
|
EXPLICIT_ACCESSW AccessEntries[2];
|
||||||
ACCESS_MASK AccessRights;
|
|
||||||
PACL Dacl;
|
PACL Dacl;
|
||||||
BOOL DaclPresent, DaclDefaulted;
|
BOOL DaclPresent, DaclDefaulted;
|
||||||
DWORD Size;
|
DWORD Size;
|
||||||
@ -663,54 +662,40 @@ static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prepare an EXPLICIT_ACCESS for the SERVICE_QUERY_STATUS | SERVICE_START right for Everyone */
|
/* prepare an EXPLICIT_ACCESS for the SERVICE_QUERY_STATUS | SERVICE_START rights for Everyone */
|
||||||
AccessEntry.grfAccessPermissions = SERVICE_QUERY_STATUS | SERVICE_START;
|
AccessEntries[0].grfAccessPermissions = SERVICE_QUERY_STATUS | SERVICE_START;
|
||||||
AccessEntry.grfAccessMode = GRANT_ACCESS;
|
AccessEntries[0].grfAccessMode = GRANT_ACCESS;
|
||||||
AccessEntry.grfInheritance = NO_INHERITANCE;
|
AccessEntries[0].grfInheritance = NO_INHERITANCE;
|
||||||
AccessEntry.Trustee.pMultipleTrustee = 0;
|
AccessEntries[0].Trustee.pMultipleTrustee = 0;
|
||||||
AccessEntry.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
AccessEntries[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
||||||
AccessEntry.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
AccessEntries[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||||
AccessEntry.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
|
AccessEntries[0].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
|
||||||
AccessEntry.Trustee.ptstrName = WorldSid;
|
AccessEntries[0].Trustee.ptstrName = WorldSid;
|
||||||
|
|
||||||
/* get the effective rights for Everyone */
|
/* prepare an EXPLICIT_ACCESS to deny the SERVICE_STOP right to Everyone */
|
||||||
AccessRights = 0;
|
AccessEntries[1].grfAccessPermissions = SERVICE_STOP;
|
||||||
if (DaclPresent && 0 != Dacl)
|
AccessEntries[1].grfAccessMode = DENY_ACCESS;
|
||||||
|
AccessEntries[1].grfInheritance = NO_INHERITANCE;
|
||||||
|
AccessEntries[1].Trustee.pMultipleTrustee = 0;
|
||||||
|
AccessEntries[1].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
||||||
|
AccessEntries[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||||
|
AccessEntries[1].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
|
||||||
|
AccessEntries[1].Trustee.ptstrName = WorldSid;
|
||||||
|
|
||||||
|
/* create a new security descriptor with the new access */
|
||||||
|
LastError = BuildSecurityDescriptorW(0, 0, 2, AccessEntries, 0, 0, SecurityDescriptor,
|
||||||
|
&Size, &NewSecurityDescriptor);
|
||||||
|
if (0 != LastError)
|
||||||
{
|
{
|
||||||
LastError = GetEffectiveRightsFromAclW(Dacl, &AccessEntry.Trustee, &AccessRights);
|
Result = FspNtStatusFromWin32(LastError);
|
||||||
if (0 != LastError)
|
goto exit;
|
||||||
/*
|
|
||||||
* Apparently GetEffectiveRightsFromAclW can fail with ERROR_CIRCULAR_DEPENDENCY
|
|
||||||
* in some rare circumstances. Calling GetEffectiveRightsFromAclW is not essential
|
|
||||||
* in this instance. It is only done to check whether the "Everyone/World" SID
|
|
||||||
* already has the access required to start the FSD; if it does not have those
|
|
||||||
* rights already they are added. It is probably safe to just assume that the
|
|
||||||
* required rights are not there if GetEffectiveRightsFromAclW fails; the worst
|
|
||||||
* that can happen is that the rights get added twice (which is benign).
|
|
||||||
*
|
|
||||||
* See https://github.com/winfsp/winfsp/issues/62
|
|
||||||
*/
|
|
||||||
AccessRights = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do we have the required access rights? */
|
/* set the new service security descriptor DACL */
|
||||||
if (AccessEntry.grfAccessPermissions != (AccessRights & AccessEntry.grfAccessPermissions))
|
if (!SetServiceObjectSecurity(SvcHandle, DACL_SECURITY_INFORMATION, NewSecurityDescriptor))
|
||||||
{
|
{
|
||||||
/* create a new security descriptor with the new access */
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
LastError = BuildSecurityDescriptorW(0, 0, 1, &AccessEntry, 0, 0, SecurityDescriptor,
|
goto exit;
|
||||||
&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;
|
Result = STATUS_SUCCESS;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user