Joe J
Joe J

Reputation: 359

SetEntriesInAcl fails and GetLastError returns 87

I am trying to take away write permissions for a given file. I am using the sample code from MSDN for this: https://learn.microsoft.com/en-us/windows/win32/secauthz/modifying-the-acls-of-an-object-in-c--

However, this sample does not work. The call to the SetEntriesInAcl function fails and GetLastError returns 87.

This thread Reasons for SetEntriesInAcl error 87 in MSDN sample says that the problem occurs if the EXPLICIT_ACCESS structure has a size of 40 instead of 48, but in my case sizeof(EXPLICIT_ACCESS) returns 48. I am using Windows 11.

How can I solve this problem? To run the code below, write the correct SID to the trustee variable and the path to your file to the objectName variable.

#include <aclapi.h>
#include <windows.h>
#include <stdio.h>

#include <iostream>

DWORD AddAceToObjectsSecurityDescriptor(
    LPTSTR pszObjName,          // name of object
    SE_OBJECT_TYPE ObjectType,  // type of object
    LPTSTR pszTrustee,          // trustee for new ACE
    TRUSTEE_FORM TrusteeForm,   // format of trustee structure
    DWORD dwAccessRights,       // access mask for new ACE
    ACCESS_MODE AccessMode,     // type of ACE
    DWORD dwInheritance         // inheritance flags for new ACE
)
{
    DWORD dwRes = 0;
    PACL pOldDACL = NULL, pNewDACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    EXPLICIT_ACCESS ea;

    if (NULL == pszObjName)
        return ERROR_INVALID_PARAMETER;

    // Get a pointer to the existing DACL.

    dwRes = GetNamedSecurityInfo(pszObjName, ObjectType,
        DACL_SECURITY_INFORMATION,
        NULL, NULL, &pOldDACL, NULL, &pSD);
    if (ERROR_SUCCESS != dwRes) {
        printf("GetNamedSecurityInfo Error %u\n", dwRes);
        goto Cleanup;
    }

    // Initialize an EXPLICIT_ACCESS structure for the new ACE. 

    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
    ea.grfAccessPermissions = dwAccessRights;
    ea.grfAccessMode = AccessMode;
    ea.grfInheritance = dwInheritance;
    ea.Trustee.TrusteeForm = TrusteeForm;
    ea.Trustee.ptstrName = pszTrustee;

    // Create a new ACL that merges the new ACE
    // into the existing DACL.

    dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
    if (ERROR_SUCCESS != dwRes) {
        printf("SetEntriesInAcl Error %u\n", dwRes);
        goto Cleanup;
    }

    // Attach the new ACL as the object's DACL.

    dwRes = SetNamedSecurityInfo(pszObjName, ObjectType,
        DACL_SECURITY_INFORMATION,
        NULL, NULL, pNewDACL, NULL);
    if (ERROR_SUCCESS != dwRes) {
        printf("SetNamedSecurityInfo Error %u\n", dwRes);
        goto Cleanup;
    }

Cleanup:

    if (pSD != NULL)
        LocalFree((HLOCAL)pSD);
    if (pNewDACL != NULL)
        LocalFree((HLOCAL)pNewDACL);

    return dwRes;
}

int main()
{
    wchar_t trustee[] = L"S-1-5-21-#-#-#-#";
    wchar_t objectName[] = L"C:\\Users\\Username\\Desktop\\acl.txt";
    AddAceToObjectsSecurityDescriptor(objectName, SE_FILE_OBJECT, trustee, TRUSTEE_IS_SID, FILE_GENERIC_WRITE, DENY_ACCESS, NO_INHERITANCE);
}

Upvotes: -1

Views: 43

Answers (0)

Related Questions