On Fri, Sep 23, 2016 at 10:39 AM, Goku Balu <tfa.signup.te...@gmail.com> wrote: > On Tue, Sep 20, 2016 at 9:30 PM, <python-win32-requ...@python.org> wrote: >> > >> > That doesn't seem like a bug to me. GENERIC_WRITE represents several >> > permissions mashed together, including FILE_WRITE and read control. >> > >> > Perhaps try with just FILE_WRITE on its own? >> >> For a file or directory, GENERIC_WRITE (0x80000000) gets mapped to >> FILE_GENERIC_WRITE, which includes the following standard rights >> (upper 16 bits): >> >> SYNCHRONIZE = 0x00100000 >> READ_CONTROL = 0x00020000 >> >> and File-object specific rights (lower 16 bits): >> >> FILE_WRITE_ATTRIBUTES = 0x00000100 >> FILE_WRITE_EA = 0x00000010 >> FILE_APPEND_DATA = 0x00000004 >> FILE_WRITE_DATA = 0x00000002 >> >> The relevant access right that's being denied in this case is SYNCHRONIZE. > > So if we deny WRITE then SYNCHRONIZE will be denied which will in-turn > affect READ. Is there a way to deny WRITE alone without affecting > file/folder read?
Each kernel object type has a GENERIC_MAPPING that maps generic rights to sets of standard and object-specific rights. Before doing an AccessCheck, generic rights have to be mapped to specific rights via MapGenericMask. For the File type this generic mapping consists of the following values: FILE_GENERIC_READ FILE_GENERIC_WRITE FILE_GENERIC_EXECUTE FILE_ALL_ACCESS If you deny GENERIC_WRITE for a File, that's the same as denying the 6 rights in FILE_GENERIC_WRITE, which includes the standard SYNCHRONIZE and READ_CONTROL rights. You need to mask the value to filter out rights that shouldn't be denied. Use the constant SPECIFIC_RIGHTS_ALL, which is defined as 0xFFFF (i.e. the lower 16 bits of an access mask are reserved for object-specific rights). For example: import win32security import ntsecuritycon WORLD = win32security.CreateWellKnownSid(win32security.WinWorldSid) FILE_WRITE = (ntsecuritycon.FILE_GENERIC_WRITE & ntsecuritycon.SPECIFIC_RIGHTS_ALL) def deny_write(filename, account=None, ace_flags=0): sd = win32security.GetFileSecurity( filename, win32security.DACL_SECURITY_INFORMATION) sid = WORLD if account is None else ( win32security.LookupAccountName(None, account)[0]) dacl = sd.GetSecurityDescriptorDacl() dacl.AddAccessDeniedAceEx( win32security.ACL_REVISION_DS, ace_flags, FILE_WRITE, sid) sd.SetSecurityDescriptorDacl(1, dacl, 0) win32security.SetFileSecurity( filename, win32security.DACL_SECURITY_INFORMATION, sd) For a directory, generic write access entails the ability to write attributes and add files and subdirectories. Note that file delete rights are separately controlled by standard DELETE access and the specific directory right FILE_DELETE_CHILD, which is the right to delete files or subdirectories of a directory, even if the user is otherwise denied or not granted DELETE access. The ace_flags parameter allows controlling whether the ACE is inherited by subdirectories and files (CONTAINER_INHERIT_ACE, OBJECT_INHERIT_ACE) , whether the inheritance flags get propagated (NO_PROPAGATE_INHERIT_ACE), and whether the ACE applies only for inheritance (INHERIT_ONLY_ACE). _______________________________________________ python-win32 mailing list python-win32@python.org https://mail.python.org/mailman/listinfo/python-win32