最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Default file permissions in Windows - Stack Overflow

programmeradmin1浏览0评论

Let's assume that we have a parent_folder folder on our Windows desktop, inside of which we have created a test.txt file.

This file has FILE_EXECUTE permissions by default after creation. As far as I understand, this file inherits these permissions from the parent parent_folder folder because we did not explicitly set these permissions for this file. Inheritance is also confirmed by the fact that ACE_HEADER::AceFlags of this file contains the INHERITED_ACE flag (proof is below).

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

int main()
{
    wchar_t objectName[] = L"C:\\Users\\Username\\Desktop\\parent_folder\\test.txt";

    wchar_t trusteeSID[] = L"S-1-5-21-#-#-#-#";
    PSID pSid;
    if (!ConvertStringSidToSid(trusteeSID, &pSid)) {
        std::cout << "ConvertStringSidToSid failed\n";
        return 0;
    }

    PACL pOldDACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    DWORD dwRes = GetNamedSecurityInfo(objectName, SE_FILE_OBJECT,
        DACL_SECURITY_INFORMATION,
        NULL, NULL, &pOldDACL, NULL, &pSD);
    if (ERROR_SUCCESS != dwRes) {
        printf("GetNamedSecurityInfo Error %u\n", dwRes);
        return EXIT_FAILURE;
    }

    for (WORD i = 0; i < pOldDACL->AceCount; i++)
    {
        PACE_HEADER header;
        GetAce(pOldDACL, i, (PVOID*)&header);

        auto ace = (ACCESS_DENIED_ACE*)header;
        if (EqualSid((PSID)&ace->SidStart, pSid) != 0)
        {
            if ((header->AceFlags & INHERITED_ACE) == INHERITED_ACE)
            {
                std::cout << "This ACE is inherited\n";
                if ((ace->Mask & FILE_EXECUTE) == FILE_EXECUTE)
                {
                    std::cout << "FILE_EXECUTE rights exists\n";
                }
                std::cout << "Ace type: " << (header->AceType == ACCESS_ALLOWED_ACE_TYPE) << std::endl;
            }
        }
    }
}

Now if I Deny FILE_EXECUTE on parent_folder, test.txt still has FILE_EXECUTE flag. My question is why does this happen, since we have Deny FILE_EXECUTE on the parent folder? I do Deny FILE_EXECUTE for the parent_folder like this:

#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;
}

#include <sddl.h>

int main()
{
    wchar_t objectName[] = L"C:\\Users\\Username\\Desktop\\parent_folder";

    wchar_t trusteeSID[] = L"S-1-5-21-#-#-#-#";
    PSID pSid;
    if (!ConvertStringSidToSid(trusteeSID, &pSid)) {
        std::cout << "ConvertStringSidToSid failed\n";
        return 0;
    }

    AddAceToObjectsSecurityDescriptor(objectName, SE_FILE_OBJECT, (PWSTR)pSid, TRUSTEE_IS_SID, FILE_EXECUTE, DENY_ACCESS, NO_INHERITANCE);
}

Even though I Deny FILE_EXECUTE for the parent folder, I still get an inherited ACE with FILE_EXECUTE permission for the file test.txt. Where does this permission come from if we took it away from the parent folder and by the way, what does FILE_EXECUTE for folders? Can folders be executable?

发布评论

评论列表(0)

  1. 暂无评论