is there a way to check if an ACE
already exists in the DACL
of an object?
I want to use the RtlAddAccessAllowedAce
API call to add an ACE
to an object, but I want to do that only if the ACE
doesn't exist already.
Does someone know how can I either check if the ACE
already exist, or to try to remove the given ACE
before adding it, or any other solution which will achieve the same goal? Thanks!
you can or use winapi or direct walk by ACL ACEs - enumerate ACE one by one and check are some specific ACE exist:
variant 1:
void WalkAcl(PACL acl)
{
ACL_SIZE_INFORMATION asi;
if (GetAclInformation(acl, &asi, sizeof(asi), AclSizeInformation))
{
if (asi.AceCount)
{
do
{
union {
PVOID pvAce;
PACE_HEADER pAceHeader;
PACCESS_ALLOWED_ACE pAllowedAce;
};
PWSTR szSid;
if (GetAce(acl, --asi.AceCount, &pvAce))
{
switch (pAceHeader->AceType)
{
case ACCESS_ALLOWED_ACE_TYPE:
if (ConvertSidToStringSid(&pAllowedAce->SidStart, &szSid))
{
DbgPrint("%08x %S\n", pAllowedAce->Mask, szSid);
LocalFree(szSid);
}
break;
}
}
} while (asi.AceCount);
}
}
}
variant 2:
void WalkAcl(PACL acl)
{
if (USHORT AceCount = acl->AceCount)
{
union {
PVOID pv;
PBYTE pb;
PACE_HEADER pAceHeader;
PACCESS_ALLOWED_ACE pAllowedAce;
};
pv = acl + 1;
do
{
UNICODE_STRING usSid;
switch (pAceHeader->AceType)
{
case ACCESS_ALLOWED_ACE_TYPE:
if (0 <= RtlConvertSidToUnicodeString(&usSid, &pAllowedAce->SidStart, TRUE))
{
DbgPrint("%08x %wZ\n", pAllowedAce->Mask, usSid);
RtlFreeUnicodeString(&usSid);
}
break;
}
} while (pb += pAceHeader->AceSize, --AceCount);
}
}