1

我正在尝试以只有所有者(甚至其他管理员)才能访问文件的方式修改 Windows 对文件的访问权限。有点相当于 unix chmod 700 文件。

我玩过拒绝一般组(EVERYONE,ADMINISTRATORS)的权限并将它们授予当前用户,但当前用户也总是失去权限。

我试图更改顺序(eas[0]、eas[1])和其他东西,但没有成功。

任何人的想法?

    EXPLICIT_ACCESSA ea= { 0, }, eas[5]= { { 0, }, };
    PACL pacl= 0;

    ea.grfAccessPermissions = GENERIC_ALL;
    ea.grfAccessMode = DENY_ACCESS ;
    ea.grfInheritance = NO_INHERITANCE;
    ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea.Trustee.ptstrName = "EVERYONE";
    eas[0]= ea;


    ea.grfAccessPermissions = GENERIC_ALL;
    ea.grfAccessMode = GRANT_ACCESS ;
    ea.grfInheritance = NO_INHERITANCE;
    ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
    ea.Trustee.ptstrName = "CURRENT_USER";
    eas[1]= ea;

    rc= SetEntriesInAcl(2, &eas[0], NULL, &pacl);

    rc= SetNamedSecurityInfoA((LPSTR)filename, SE_FILE_OBJECT,
                                    DACL_SECURITY_INFORMATION,
                                    NULL, NULL, pacl, NULL);
4

3 回答 3

4

在大多数情况下,拒绝条目优先于允许条目。由于默认情况下拒绝访问,因此您不需要拒绝条目,但是您需要禁用继承的权限。您可以通过使用PROTECTED_DACL_SECURITY_INFORMATION标志来做到这一点。

#include <Windows.h>
#include <Aclapi.h>

#include <stdio.h>

int main(int argc, char ** argv)
{
    EXPLICIT_ACCESS eas[1];
    PACL pacl = 0;
    DWORD rc;

    eas[0].grfAccessPermissions = GENERIC_ALL;
    eas[0].grfAccessMode = GRANT_ACCESS;
    eas[0].grfInheritance = NO_INHERITANCE;
    eas[0].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    eas[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    eas[0].Trustee.ptstrName = L"CURRENT_USER";

    rc = SetEntriesInAcl(1, &eas[0], NULL, &pacl);
    if (rc != ERROR_SUCCESS)
    {
        printf("SetEntriesInAcl: %u\n", rc);
        return 1;
    }

    rc = SetNamedSecurityInfo(L"C:\\working\\test.txt", SE_FILE_OBJECT, 
             DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, 
             NULL, NULL, pacl, NULL);
    if (rc != ERROR_SUCCESS)
    {
        printf("SetNamedSecurityInfo: %u\n", rc);
        return 1;
    }

    printf("OK!\n");
    return 0;
}

请注意,管理员始终可以重置权限以获得对文件的访问权限。如果您确实需要保护数据免受其他管理员的侵害,则必须对其进行加密。(并希望没有人安装键盘记录器来窃取您的加密密码。)

于 2017-02-09T23:24:41.187 回答
1

虽然在技术上是可行的,但它在保护对象方面并没有给您带来太多好处。给定具有适当条目的 DACL,本地管理员可能无法立即访问文件,但他们始终可以获取系统中任何对象的所有权。这使他们可以完全控制对象,并且可以操纵其 DACL 和 SACL。

于 2017-02-09T17:14:43.457 回答
1

正式你需要下一个代码

DWORD demo(PCWSTR filename)
{
    EXPLICIT_ACCESS ea= { 
        GENERIC_ALL, 
        GRANT_ACCESS, 
        NO_INHERITANCE, 
        { 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME, TRUSTEE_IS_USER, L"CURRENT_USER"}
    };
    PACL pacl;

    DWORD err = SetEntriesInAcl(1, &ea, NULL, &pacl);

    if (!err)
    {
        err = ERROR_GEN_FAILURE;

        if (pacl->AceCount == 1)
        {
            union {
                PVOID pvAce;
                PACE_HEADER Header;
                PACCESS_ALLOWED_ACE pAce;
            };

            if (GetAce(pacl, 0, &pvAce) && Header->AceType == ACCESS_ALLOWED_ACE_TYPE)
            {
                HANDLE hFile = CreateFile(filename, WRITE_DAC|WRITE_OWNER, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);

                if (hFile != INVALID_HANDLE_VALUE)
                {
                    SECURITY_DESCRIPTOR sd;
                    InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
                    SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE);
                    SetSecurityDescriptorOwner(&sd, &pAce->SidStart, FALSE);
                    SetSecurityDescriptorControl(&sd, SE_DACL_PROTECTED, SE_DACL_PROTECTED);

                    err = SetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION, &sd)
                        ? NOERROR : GetLastError();

                    CloseHandle(hFile);
                }
                else
                {
                    err = GetLastError();
                }
            }
        }

        LocalFree(pacl);
    }

    return err;
}

注释行

SetSecurityDescriptorControl(&sd, SE_DACL_PROTECTED, SE_DACL_PROTECTED);

使用此DACL文件代码将只有一个条目 -GENERIC_ALL对于当前用户。以及 DACL 中明确不允许的所有内容 - 被拒绝。但当然,如果用户有SE_TAKE_OWNERSHIP_PRIVILEGE权限 - 您可以打开具有WRITE_OWNER访问权限的文件并将自己设置为所有者。在此之后,您可以打开文件WRITE_DAC并更改 DACL


如前所述,@Harry Johnston 代码可以更短,如果使用SetNamedSecurityInfo

DWORD demo(PCWSTR filename)
{
    EXPLICIT_ACCESS ea= { 
        GENERIC_ALL, 
        GRANT_ACCESS, 
        NO_INHERITANCE, 
        { 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME, TRUSTEE_IS_USER, L"CURRENT_USER"}
    };
    PACL pacl;

    DWORD err = SetEntriesInAcl(1, &ea, NULL, &pacl);

    if (!err)
    {
        err = ERROR_GEN_FAILURE;

        if (pacl->AceCount == 1)
        {
            union {
                PVOID pvAce;
                PACE_HEADER Header;
                PACCESS_ALLOWED_ACE pAce;
            };

            if (GetAce(pacl, 0, &pvAce) && Header->AceType == ACCESS_ALLOWED_ACE_TYPE)
            {
                err = SetNamedSecurityInfo((PWSTR)filename, SE_FILE_OBJECT, 
                    DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION |PROTECTED_DACL_SECURITY_INFORMATION, 
                    &pAce->SidStart, NULL, pacl, NULL);
            }
        }

        LocalFree(pacl);
    }

    return err;
}
于 2017-02-09T18:23:38.923 回答