Search code examples
securitypermissionsfile-permissionsdacl

Am I using SetNamedSecurityInfo incorrectly? The ACL of my file doesn't seem to be being modified properly


I'm trying to enable and disable certain access privileges on a file. I figured out that to do this, you have to mess with DACLs. I'm using the following code to modify the file's DACL:

 void set_DACL_for_object(const char *object, SE_OBJECT_TYPE object_type,
                          int access_perms, int access_mode) {

      PACL pDACL = NULL, pOldDACL = NULL;
      PSECURITY_DESCRIPTOR pSD = NULL;
      EXPLICIT_ACCESS ea;

      GetNamedSecurityInfo((LPTSTR)object, object_type,
                            DACL_SECURITY_INFORMATION, NULL, NULL,
                            &pOldDACL, NULL, &pSD);

      ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));

      ea.grfAccessPermissions = access_perms;
      ea.grfAccessMode = access_mode;
      ea.grfInheritance = NO_INHERITANCE;
      ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
      ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
      ea.Trustee.ptstrName = _T("ADMINISTRATORS");

      SetEntriesInAcl(1, &ea, pOldDACL, &pDACL);

      SetNamedSecurityInfo((LPTSTR)object, object_type,
                            DACL_SECURITY_INFORMATION, NULL, NULL, pDACL, NULL);
 }

So first I'm creating a file with fopen(), creating an ACL to give all access to the Administrators group, and then denying write access to the Administrators group:

 set_DACL_for_object("C:\\file.txt", SE_FILE_OBJECT, GENERIC_ALL, SET_ACCESS);
 set_DACL_for_object("C:\\file.txt", SE_FILE_OBJECT, GENERIC_WRITE, DENY_ACCESS);

However, after these calls I have no read access to the file. If I don't make the calls, I have read/write access (as would be expected).

I should note I'm running under an admin account and the functions are returning as successful. I also tried modifying the ACL for a specific limited user, but the same thing happens... the user is denied read access, not write access like I wanted.

I tried a bunch of different combos of calls to set_DACL_for_object(), like replacing DENY_ACCESS with REVOKE_ACCESS, SET_ACCESS with GRANT_ACCESS, not making any SET_ACCESS calls, etc, etc, but nothing seems to work.

I should note, most of the code was taken from this MSDN example, so I would think it should work. What exactly am I doing wrong?


Solution

  • Open and read it in which program? The ACL was set to what i expected, but FILE_GENERIC_WRITE may be too generic for your purposes; it looks like that also sets a 'special' permission that affects reading attributes.

    from winnt.h:

    #define FILE_GENERIC_WRITE        (STANDARD_RIGHTS_WRITE    |\
                                       FILE_WRITE_DATA          |\
                                       FILE_WRITE_ATTRIBUTES    |\
                                       FILE_WRITE_EA            |\
                                       FILE_APPEND_DATA         |\
                                       SYNCHRONIZE)
    

    if i call with a more limited set of flags the test file can now be opened and read, at least in notepad, but the administrator user can not save the document:

    DWORD dwCustomWrite = FILE_WRITE_DATA       | 
                          FILE_WRITE_ATTRIBUTES | 
                          FILE_WRITE_EA         | 
                          FILE_APPEND_DATA;
    set_DACL_for_object(..., SE_FILE_OBJECT, dwCustomWrite, DENY_ACCESS);
    

    on the advanced permissions list from the security tab on the file, with the above call only the following are marked as 'deny' for the 'administrators' group:

    'Create files / write data', 'create folders / append data', 'Write attributes', 'Write extended attributes'

    With this knowledge you should be able to pick the exact set of flags you need.