Using C++, I want to remove (not deny) Write permission alone from a user trustee with Full Control permission in Windows NTFS Folder.

Praveenkumar S 20 Reputation points
2025-01-31T07:07:53.5766667+00:00

I want to implement a C++ program that removes the "Write" permission alone for a user trustee with "Full Control" permission over a folder on a Windows NTFS drive.

I tried to use the SetEntriesInAcl() function from the aclapi.h API,

but I failed to do so because "REVOKE_ACCESS" AccessMode removed the trustee itself.

I want to remove Write access (that is, I do not want to set a deny or allow access type). Please help me achieve this.

Note: I also tried the below method, which I do not want. Since it is not the correct solution for my needs.

I used "SET_ACCESS" as grfAccessMode, "GENERIC_READ | GENERIC_EXECUTE" as grfAccessPermissions and "SUB_CONTAINERS_AND_OBJECTS_INHERIT" as grfInheritance in EXPLICIT_ACCESS structure for SetEntriesInAcl function. - this gives the final result without "Write" permission, but our action is not like removing Specific permission alone.

Windows
Windows
A family of Microsoft operating systems that run across personal computers, tablets, laptops, phones, internet of things devices, self-contained mixed reality headsets, large collaboration screens, and other devices.
5,763 questions
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,723 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,842 questions
Windows 10 Security
Windows 10 Security
Windows 10: A Microsoft operating system that runs on personal computers and tablets.Security: The precautions taken to guard against crime, attack, sabotage, espionage, or another threat.
2,995 questions
{count} votes

Accepted answer
  1. RLWA32 46,756 Reputation points
    2025-01-31T17:07:04.8266667+00:00

    Following incomplete snippet removes write access and leaves any other permissions in the access mask unchanged.

    err = GetExplicitEntriesFromAcl(pDacl, &nEntries, &pExplicit);
    if (!err)
    {
        for (ULONG i = 0; i < nEntries; i++)
        {
            PEXPLICIT_ACCESS pea = &pExplicit[i];
            if (pea->Trustee.TrusteeForm != TRUSTEE_IS_SID)
            {
                _tprintf(_T("Trustee form was not a SID\n"));
                continue;
            }
            if (pea->Trustee.TrusteeForm == TRUSTEE_IS_SID)
            {
                if (EqualSid((PSID)pea->Trustee.ptstrName, pts2->Sid))
                {
                    PACL pNewDacl{};
    
                    pea->grfAccessMode = SET_ACCESS;
    
                    // Remove permissions from access mask
                    pea->grfAccessPermissions &= ~(WRITE_DAC | WRITE_OWNER | DELETE); // Standard rights
                    pea->grfAccessPermissions &= ~(FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_DELETE_CHILD); // specific rights
    
                    err = SetEntriesInAcl(1, pea, pDacl, &pNewDacl);
                    if (!err)
                    {
                        err = SetNamedSecurityInfo(szFolder, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
                            nullptr, nullptr, pNewDacl, nullptr);
    
                        if (err)
                            ShowLastError(_T("SetNamedSecurityInfo"), err);
    
                        LocalFree(pNewDacl);
                    }
                    else
                        ShowLastError(_T("SetEntriesInAcl"), err);
    
                    break;
                }
            }
        }
    
        LocalFree(pExplicit);
    }
    else
        ShowLastError(_T("GetExplicitEntriesFromAcl"), err);
    

    The assumption used is that its OK to let SetNamedSecurityInfo handle propagation of permissions to subfolders/files based on the existing settings in the security descriptor.

    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.