Thanks Eryk for being so thorough and for a great explanation. If this can be solved differently, I tried with removing the rights such as READ_CONTROL and SYNCHRONIZE from the FILE_GENERIC_WRITE mask and it worked as well.
masks= ntsecuritycon.FILE_GENERIC_WRITE masks=masks&~ntsecuritycon.READ_CONTROL masks=masks&~ntsecuritycon.SYNCHRONIZE Really appreciate the great community help. Thanks, Goku On Fri, Sep 23, 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). > > For reference, here's an access mask diagram: > > 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 > 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 > +---------------+---------------+-------------------------------+ > |G|G|G|G|Resvd|A| StandardRights| SpecificRights | > |R|W|E|A| |S| | | > +-+-------------+---------------+-------------------------------+ > > Generic Read > Generic Write > Generic Execute > Generic All > Reserved: 3 > Access SACL > Standard Rights: 8 > Specific Rights: 16 > > The four most significant bits are the generic rights. Before > evaluating an AccessCheck, the system maps generic rights in access > masks to the corresponding standard and specific rights. > > Only 5 of the 8 possible standard rights have been assigned: > SYNCHRONIZE (bit 20), WRITE_OWNER, WRITE_DAC, READ_CONTROL, and DELETE > (bit 16). > > The File type assigns 9 out of 16 possible specific rights, from > FILE_WRITE_ATTRIBUTES (bit 8) down to FILE_READ_DATA (bit 0). Some > bits have multiple meanings depending on whether the object is a > directory, data file, or named pipe. For example, bit 2 can mean > FILE_ADD_SUBDIRECTORY, FILE_APPEND_DATA, or FILE_CREATE_PIPE_INSTANCE. > >
_______________________________________________ python-win32 mailing list python-win32@python.org https://mail.python.org/mailman/listinfo/python-win32