views:

487

answers:

2

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 = (LPTSTR)"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?

A: 

hey, i think the set_DACL_for_object calls should specify FILE_ALL_ACCESS and FILE_GENERIC_WRITE, not GENERIC_ALL and GENERIC_WRITE. i compiled your code snippet with these changes and it worked as you expect.

as a side note the LPTSTR cast prevents the compiler from detecting that this code is ansi in a unicode build environment, so a head's up in case you try plopping this into a unicode environment. fortunately the APIs fail in a predictable way when this is the case.

~jewels

Jewel S
Thanks; I tried that, and it still produces the same results for me (can't read the file). On your system, calling both of those functions -- SET_ACCESS for FILE_ALL_ACCESS and DENY_ACCESS for FILE_GENERIC_WRITE -- allows you to open up the file and read it, but not write it?
ZZZzzz
+1  A: 

replying here so i can get formatting. :)

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.

~jewels

Jewel S
Thanks! That did it. After I replied to your first answer, I booted into Safe Mode and checked the Security info on the file I was creating and modifying the ACL for. I noticed that write access was indeed denied, and read access allowed... but there were also some special permissions being denied as well. Thanks for pointing me in the right direction, now it's working.
ZZZzzz