What does ERROR_BAD_INHERITANCE_ACL
returned from SetNamedSecurityInfo imply? In this case I'm adding a user to a directory's ACL. I've looked at the directory in question and its rights seem reasonable before the call. But the calls fails.
Any thoughts?
Here is the code snippet doing the work (and as I paste it here, I'm wondering about the NO_MULTIPLE_TRUSTEE
value):
pAAP is a pointer to a structure with the following members:
CString objName; // name of object
SE_OBJECT_TYPE ObjectType; // type of object
CString trustee; // trustee for new ACE (explicit user name)
CString targetComputer;
bool bNeedWrite;
DWORD dwRes = 0;
PACL pOldDACL = NULL, pNewDACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea = {0};
CSID trusteeSID;
bool bGotSID = false;
if(0 == wcsncmp(pAAP->trustee, L"SID:", 4)) //4 = len of SID: //GLOK
bGotSID = CSID::FromString((LPWSTR)((LPCWSTR)pAAP->trustee + 4), trusteeSID);
else
bGotSID = CSID::FromAccount(pAAP->targetComputer, pAAP->trustee, trusteeSID);
if(false == bGotSID)
{
Log(logDEBUG, L"CSID::FromAccount failed for [%s] on [%s]. GLE=%s", pAAP->trustee, pAAP->targetComputer, GetSystemErrorMessage(GetLastError()));
_ASSERT(0);
goto Cleanup;
}
// Get a pointer to the existing DACL.
dwRes = GetNamedSecurityInfo(pAAP->objName.LockBuffer(), pAAP->ObjectType, DACL_SECURITY_INFORMATION,
NULL, NULL, &pOldDACL, NULL, &pSD);
pAAP->objName.UnlockBuffer();
if (ERROR_SUCCESS != dwRes)
{
Log(logDEBUG, L"GetNamedSecurityInfo failed on [%s] for [%s] on [%s]. GLE=%s", pAAP->objName, pAAP->trustee, pAAP->targetComputer, GetSystemErrorMessage(dwRes));
//_ASSERT(ERROR_FILE_NOT_FOUND == dwRes);
goto Cleanup;
}
// Initialize an EXPLICIT_ACCESS structure for the new ACE.
ea.grfAccessPermissions = pAAP->bNeedWrite ? GENERIC_ALL : GENERIC_READ;
ea.grfAccessMode = GRANT_ACCESS;
ea.grfInheritance= CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
ea.Trustee.ptstrName = (LPWSTR)(PSID)trusteeSID;
ea.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
// Create a new ACL that merges the new ACE into the existing DACL.
dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
if (ERROR_SUCCESS != dwRes)
{
Log(logDEBUG, L"SetEntriesInAcl failed on [%s] for [%s] on [%s]. GLE=%s", pAAP->objName, pAAP->trustee, pAAP->targetComputer, GetSystemErrorMessage(dwRes));
//_ASSERT(0);
goto Cleanup;
}
// Attach the new ACL as the object's DACL.
dwRes = SetNamedSecurityInfo(pAAP->objName.LockBuffer(), pAAP->ObjectType, DACL_SECURITY_INFORMATION,
NULL, NULL, pNewDACL, NULL);
if (ERROR_SUCCESS != dwRes)
{
Log(logDEBUG, L"SetNamedSecurityInfo failed on [%s] for [%s] on [%s]. GLE=%s", pAAP->objName, pAAP->trustee, pAAP->targetComputer, GetSystemErrorMessage(dwRes));
//_ASSERT(dwRes == ERROR_BAD_INHERITANCE_ACL);
goto Cleanup;
}
Cleanup:
if(pSD != NULL)
LocalFree((HLOCAL) pSD);
if(pNewDACL != NULL)
LocalFree((HLOCAL) pNewDACL);