I would like to be able to authorize or deny write access to a specific directory on Windows XP and more.
I tried the following, and they all don't work:
os.chmod()
: only a file read-only attribute can be specified, see Python's docwin32api.SetFileAttribute()
FILE_ATTRIBUTE_READONLY: A file that is read-only. [...] This attribute is not honored on directories, see MSDN's SetFileAttribute
It looks like the only alternative I have is to access and update the "Security info" of the directory, I've tried for several hours to get something done with this without much success (I'm really unfamiliar with Win32 API).
Any ideas on how to do that?
This was just challenging thing to do. I've started with this really great answer which helps you with a similar thing.
You can start by just listing ACLs for directory, which could be done using this code:
You can find method
PyACL.GetAceCount()
which returns number of ACEs.The
GetAce(i)
function returnsACCESS_ALLOWED_ACE
header as atuple
:ACE_HEADER
- two integersAceType
,AceFlags
- trial and error showed me thatAceFlags
set to11
meant inherit privileges and3
not inheritedACCESS_MASK
- detailed list here or inntsecuritycon.py
SID
Now you are able to read old ACEs and deleting old ones is quite simple:
And after that you can just add privileges by calling
AddAccessAllowedAceEx()
[MSDN]:I've taken numbers
3
,2032127
and1179785
from the listing in first half of the script (before running the script I've set up privileges in Explorer->Right Click->Properties->Security->Advanced):Just illustrative image borrowed from http://technet.microsoft.com/
But it corresponds to:
OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE
FILE_ALL_ACCESS
(well, actuallycon.FILE_ALL_ACCESS = 2032639
, but once you apply it on file and read it back you'll get 2032127; the difference is 512 - 0x0200 - the constant I haven't found inntsecuritycon.py/file security permissions
)FILE_GENERIC_READ
You can also remove access, change it or remove it but this should be very solid start for you.
TL;DR - codes
Mini utility for complete ACE listing
I just wrote small script for parsing all file ACEs:
It prints out strings like this:
So, by pocking around and trying to understand what was going on, I managed to find something very similar to what @Vyktor posted before.
I found some help using this example.
So, first thing I did was to try to understand the flags set by Windows when I was manually changing the security information with the GUI, I built a set of function to help me with this:
From there, I got the following informations:
This example shows the default ACL I have on my system + the first one, which is one I created myself and which denies writes on the directory.
So,using the example before, I built this:
Contrary to @Vyktor solution, I'm using a "Denied" ACE, by denying write access (whereas Vyktor added an "Allowed read-only" ACE).
I sitll miss a proper way to remove this ACE so I can write again in this directory, but I haven't really look yet. One thing which is important is that "Denied" ACE have priority over "Allowed" ACE, so I tried the naive way of using
dacl.AddAccessAllowedAceEx()
with the exact same parameters as I was using ondacl.AddAccessDeniedAceEx()
, but the later one has precedence over the former one, so I still can't write into the directory.