winapidacl

Windows Create File Access that only allows Owner to access the file (Win32)


I'm trying to modify Windows access rights to a file in a way that only the owner (not even other Administrators) can access the file. Somewhat the equivalent of unix chmod 700 file.

I've played with denying rights to the general group (EVERYONE, ADMINISTRATORS) and granting them to the current user, but the current user always also loses the rights.

I tried to change the order (eas[0], eas[1]) and stuff, but without success.

Ideas anyone?

    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);

Solution

  • In most cases, deny entries take precedent over allow entries. Since access is denied by default, you don't need the deny entry, however you will need to disable inherited permissions. You can do this by using the PROTECTED_DACL_SECURITY_INFORMATION flag.

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

    Note that an administrator can always reset the permissions in order to gain access to the file. If you really need to protect the data against other administrators you'll have to encrypt it. (And hope nobody installs a keylogger to steal your encryption password.)