Search code examples
windowssecurityacl

Failed to use AddAccessAllowedAce to append an ACE to an existing ACL


I use following code to get an ACL from SD:

...
PACL pDacl = NULL;
BOOL bDaclPresent = TRUE;
BOOL bDaclDefaulted = FALSE;
if(!GetSecurityDescriptorDacl((PSECURITY_DESCRIPTOR)spSecurityDescriptor.get(),
                                &bDaclPresent,
                                &pDacl,
                                &bDaclDefaulted))
{
    ReportError(TEXT("Failed to call GetSecurityDescriptorDacl."));
    ...
}

Then I use AddAccessAllowedAce to append a new ACE:

if(!AddAccessAllowedAce(pDacl,
                        ACL_REVISION,
                        MQSEC_QUEUE_GENERIC_ALL,
                        pAnnySid))
{
    dwErrCode = GetLastError();
    ReportError(dwErrCode);
    ReportError(TEXT("Failed to call AddAccessAllowedAce."));
    ...
}

I got an error 1344 that "No more memory is available for security information updates."

Then I tried to increase the size of PACL buffer and changed the PACL header information. But I still got an error 1336 "The access control list (ACL) structure is invalid."

Could anyone give me a working sample code to do this?

MSDN privided an sample of AddAccessAllowedAce here: http://msdn.microsoft.com/en-us/library/ms707085%28v=vs.85%29.aspx But it's about to create a brand new ACL, not the same case.

I even think to 'GetAce' from old ACL then 'AddAce' to a new ACL, in the end I append my own new ACE. But looks like 'AddAce' need a parameter 'nAceListLength'; and I don't know how to get this value from ACE.

Any ideas?


Solution

  • GetSecurityDescriptorDacl() just gives you a pointer to the DACL that is already present in the SECURITY_DESCRIPTOR buffer. If you want to add something to it you need to allocate a larger buffer, copy the existing DACL, then add the new ACE. You need to do something like the following (pseudo-code off the top of my head; may have errors):

    PACL pOldDacl = GetSecurityDescriptorDacl(pSecurityDescriptor);
    DWORD cbOldSize = GetAclInformation(pOldDacl, ACL_SIZE_INFORMATION);
    DWORD cbNewSize = cbOldSize + sizeof(ACE that you want to add);
    PACL pNewDacl = alloc(cbNewSize);
    InitializeAcl(pNewDacl, cbNewSize);
    for each pAce in pOldDacl // GetAce(pOldDacl)
        AddAce(pNewDacl, pAce);
    AddAce(pNewDacl, the ACE that you want to add); // or use specialized functions like AddAccessAllowedAce, etc
    SetSecurityDescriptorDacl(pSecurityDescriptor, pNewDacl);
    

    Microsoft KB has an article.