Reading the access attributes of directories in Windows

V

vsoler

Either use fs.dir (if you know it's a directory) or fs.entry (if it
could be a file or a directory; the code will dispatch to the right one).

If you only want the directories immediately some directory,
you could do this:

<code>
from winsys import fs, security

root = fs.file (sys.executable).path  # or fs.dir ("w:/") etc.
for d in root.dirs (ignore_access_errors=True):
   print (d, "=>", d.security ()) # or whatever

</code>

If you want to walk the tree of directories looking at permissions, then:

<code>
import os, sys
from winsys import fs

root = fs.file (sys.executable).path
for dirpath, _, _ in root.walk ():
   print (dirpath, "=>", dirpath.security ())



In fact, even if you did for some reason use os.walk, you can
easily wrap the returned filenames using fs.entry:

<code>
import os, sys
from winsys import fs

root = os.path.dirname (sys.executable)
for dirpath, filenames, dirnames in os.walk (root):
   print (dirpath, "=>", fs.entry (dirpath).security ())

</code>

TKG

Tim,

I appreciate the time and effort that you are putting in this post.

Personally, I am impressed of the power of python, your winsys
library, and overall, how easy it is to customize the scripting of
one's day to day needs.

I have started testing your first script

from winsys import fs, security
root = fs.dir ("c:/")
for d in root.dirs (ignore_access_errors=True):
print (d, "=>", d.security ())

Howwvwer, I am getting an error:
c:\$recycle.bin\ => O:BAD:pAI(A;;FA;;;BA)(A;OICIIO;GA;;;BA)(A;;FA;;;SY)
(A;OICIIO;GA;;;SY)(A;;0x1201ad;;;BU)
c:\aeat\ => O:BAD:AI(A;ID;FA;;;BA)(A;OICIIOID;GA;;;BA)(A;ID;FA;;;SY)
(A;OICIIOID;GA;;;SY)(A;OICIID;0x1200a9;;;BU)(A;ID;0x1301bf;;;AU)
(A;OICIIOID;SDGXGWGR;;;AU)
c:\archivos de programa\ => O:SYD:pAI(D;;CC;;;WD)(A;;0x1200a9;;;WD)
(A;;FA;;;SY)(A;;FA;;;BA)
c:\documents and settings\ => O:SYD:pAI(D;;CC;;;WD)(A;;0x1200a9;;;WD)
(A;;FA;;;SY)(A;;FA;;;BA)
c:\hp\ => O:SYD:AI(A;ID;FA;;;BA)(A;OICIIOID;GA;;;BA)(A;ID;FA;;;SY)
(A;OICIIOID;GA;;;SY)(A;OICIID;0x1200a9;;;BU)(A;ID;0x1301bf;;;AU)
(A;OICIIOID;SDGXGWGR;;;AU)
Traceback (most recent call last):
File "C:/Users/Vicente/Documents/VS/Python/test6.py", line 5, in
<module>
print(d, "=>",d.security())
File "C:\Python31\lib\site-packages\winsys\fs.py", line 1044, in
security
return security.security (self, options=options)
File "C:\Python31\lib\site-packages\winsys\security.py", line 585,
in security
return Security.from_object (str (obj), obj_type, options=options)
File "C:\Python31\lib\site-packages\winsys\security.py", line 475,
in from_object
sd = wrapped (win32security.GetNamedSecurityInfo, obj,
object_type, options)
File "C:\Python31\lib\site-packages\winsys\exc.py", line 55, in
_wrapped
raise exception (errno, errctx, errmsg)
winsys.security.x_security: (5, 'GetNamedSecurityInfo', 'Acceso
denegado.')
I am using a system in the Spanish language. As you can see in the
last line, 'Acceso denegado' or 'Access denied' even though the flag
"ignore_access_errors" is set to True.

I am using python 3.1 on Windows 7. What do you think is the origin of
this problem?

Vicente Soler
 
T

Tim Golden

Personally, I am impressed of the power of python, your winsys
library, and overall, how easy it is to customize the scripting of
one's day to day needs.

Glad you find it useful...

I have started testing your first script

from winsys import fs, security
root = fs.dir ("c:/")
for d in root.dirs (ignore_access_errors=True):
print (d, "=>", d.security ())

Howwvwer, I am getting an error:

c:\$recycle.bin\ => O:BAD:pAI(A;;FA;;;BA)(A;OICIIO;GA;;;BA)(A;;FA;;;SY)
(A;OICIIO;GA;;;SY)(A;;0x1201ad;;;BU)
c:\aeat\ => O:BAD:AI(A;ID;FA;;;BA)(A;OICIIOID;GA;;;BA)(A;ID;FA;;;SY)
(A;OICIIOID;GA;;;SY)(A;OICIID;0x1200a9;;;BU)(A;ID;0x1301bf;;;AU)
(A;OICIIOID;SDGXGWGR;;;AU)
c:\archivos de programa\ => O:SYD:pAI(D;;CC;;;WD)(A;;0x1200a9;;;WD)
(A;;FA;;;SY)(A;;FA;;;BA)
c:\documents and settings\ => O:SYD:pAI(D;;CC;;;WD)(A;;0x1200a9;;;WD)
(A;;FA;;;SY)(A;;FA;;;BA)
c:\hp\ => O:SYD:AI(A;ID;FA;;;BA)(A;OICIIOID;GA;;;BA)(A;ID;FA;;;SY)
(A;OICIIOID;GA;;;SY)(A;OICIID;0x1200a9;;;BU)(A;ID;0x1301bf;;;AU)
(A;OICIIOID;SDGXGWGR;;;AU)
Traceback (most recent call last):
File "C:/Users/Vicente/Documents/VS/Python/test6.py", line 5, in
<module>
print(d, "=>",d.security())
File "C:\Python31\lib\site-packages\winsys\fs.py", line 1044, in
security
return security.security (self, options=options)
File "C:\Python31\lib\site-packages\winsys\security.py", line 585,
in security
return Security.from_object (str (obj), obj_type, options=options)
File "C:\Python31\lib\site-packages\winsys\security.py", line 475,
in from_object
sd = wrapped (win32security.GetNamedSecurityInfo, obj,
object_type, options)
File "C:\Python31\lib\site-packages\winsys\exc.py", line 55, in
_wrapped
raise exception (errno, errctx, errmsg)
winsys.security.x_security: (5, 'GetNamedSecurityInfo', 'Acceso
denegado.')

I am using a system in the Spanish language. As you can see in the
last line, 'Acceso denegado' or 'Access denied' even though the flag
"ignore_access_errors" is set to True.

I am using python 3.1 on Windows 7. What do you think is the origin of
this problem?

Vicente Soler

Can you run Python from within a Run-As-Administrator command
prompt? Windows Vista & 7 bring a lot more security to the basic
Windows model. If you can't do that, it might be possible to
elevate your privileges enough to read the security attributes
using the security.change_privileges function.

TJG
 
T

Tim Golden

I am using a system in the Spanish language. As you can see in the
last line, 'Acceso denegado' or 'Access denied' even though the flag
"ignore_access_errors" is set to True.

Sorry, meant to reply to this point as well. The ignore_access_errors
flag only applies to finding the file's existence in the first place
(it's a flag to the dirs iterator) but you're getting access denied
on the attempt to read security.

If the option to run in an Administrator-enabled windows isn't applicable,
you've got a couple more options open: you could catch that specific
error in a try-except block and do something which made sense in your
context (write it to a log, discard it, whatever). You wouldn't get the
information but it wouldn't stop you proceeding.

As an alternative you could ask for slightly less information from the
security () function. By default it requests Owner and DACL info; if
you only wanted the DACL you can just pass "D" as the options parameter
to the call. Obviously, if it's the request for DACL which is giving
the access error then this won't help.

Another alternative is to enable any privileges in your access token
which aren't enabled by default. The likelihood is that, without
running in Admin mode, the disabled privs won't offer you much. You
can see what privileges you currently have by looking at your process
token:

<code>
from winsys import security

security.token ().dump ()

</code>

Look for the set of privileges: an asterisk (*) means the priv
is enabled by default; a plus (+) means it has been enabled;
a minus (-) means it has not been enabled. If you had backup
privilege enabled you would be able to read the security of
any filesystem object even if you had no rights to it.

TJG
 
N

Nobody

How does append differ from write? If you have appending permissions, but not
writing ones, is it impossible to seek? Or is there a more complex "block"
that bites you when you seek to before the old end of file and try writing
there?

If you have append permission, you can open a file in append mode. AFAICT,
this behaves the same as O_APPEND on Unix, i.e. all writes are
automatically appended to the file, regardless of the current offset.

Having this as a separate permission allows normal users to add entries to
log files but not to erase existing entries.
Makes me wonder whether SELinux makes changes in this area, and if so,
how far-reaching they are.

SELinux adds finer-grained permissions (e.g. append is distinct from
write), but also adds role-based checks, i.e. permissions are attached to
individual programs, which limits the extent to which a bug or misfeature
can be exploited.
What about both?

A file/directory only has one owner.
Really? So the operating system actually places restrictions on what the
administrator can do?

Yes, although doubtless such constraints can be circumvented (if you can
install software, you can use the account of anyone who uses the software).
Or is there a fine distinction here between administrator-accounts in general
and the NT "Administrator" account that at least some versions of Windows (xp
home edition springs to mind) appear to try to hide as best they can ?

I don't think that the "Administrator" account is special. AFAICT, any
member of the Administrators group has the same privileges.
 
V

vsoler

Either use fs.dir (if you know it's a directory) or fs.entry (if it
could be a file or a directory; the code will dispatch to the right one).

If you only want the directories immediately some directory,
you could do this:

<code>
from winsys import fs, security

root = fs.file (sys.executable).path  # or fs.dir ("w:/") etc.
for d in root.dirs (ignore_access_errors=True):
   print (d, "=>", d.security ()) # or whatever

</code>

If you want to walk the tree of directories looking at permissions, then:

<code>
import os, sys
from winsys import fs

root = fs.file (sys.executable).path
for dirpath, _, _ in root.walk ():
   print (dirpath, "=>", dirpath.security ())



In fact, even if you did for some reason use os.walk, you can
easily wrap the returned filenames using fs.entry:

<code>
import os, sys
from winsys import fs

root = os.path.dirname (sys.executable)
for dirpath, filenames, dirnames in os.walk (root):
   print (dirpath, "=>", fs.entry (dirpath).security ())

</code>

TKG

Tim,

One of your scripts still does not work on my system:


==> If you want to walk the tree of directories looking at
permissions, then:

<code>
import os, sys
from winsys import fs

root = fs.file (sys.executable).path
for dirpath, _, _ in root.walk ():
print (dirpath, "=>", dirpath.security ())
</code>

However, I get the following error:

Traceback (most recent call last):
File "C:/Local/test4.py", line 5, in <module>
root = fs.file (r'W:\FRIB\ELPR\$DATA\DPT-FINANZAS').path
File "C:\Program Files\Python31\lib\site-packages\winsys\fs.py",
line 1775, in file
raise x_fs (None, "file", "%s exists but is a directory" %
filepath)
winsys.fs.x_fs: (None, 'file', 'W:\\FRIB\\ELPR\\$DATA\\DPT-FINANZAS
exists but is a directory')

That is, I am interested in looking for directories, but the problem
is that the path is a directory.

I'm sure there must be some way to get around this problem.

Thank you

Vicente Soler
 
T

Tim Golden

Tim,

One of your scripts still does not work on my system:


==> If you want to walk the tree of directories looking at
permissions, then:

<code>
import os, sys
from winsys import fs

root = fs.file (sys.executable).path
for dirpath, _, _ in root.walk ():
print (dirpath, "=>", dirpath.security ())
</code>

However, I get the following error:

Traceback (most recent call last):
File "C:/Local/test4.py", line 5, in<module>
root = fs.file (r'W:\FRIB\ELPR\$DATA\DPT-FINANZAS').path
File "C:\Program Files\Python31\lib\site-packages\winsys\fs.py",
line 1775, in file
raise x_fs (None, "file", "%s exists but is a directory" %
filepath)
winsys.fs.x_fs: (None, 'file', 'W:\\FRIB\\ELPR\\$DATA\\DPT-FINANZAS
exists but is a directory')

That is, I am interested in looking for directories, but the problem
is that the path is a directory.

I'm sure there must be some way to get around this problem.


Replace fs.file by fs.entry: the latter detects automatically whether
it's looking at a file or at a directory. I used fs.file in my example
because I *know&* what sys.executable must be a file (python.exe). In
your case, either use fs.dir if you know it's a directory or fs.entry
if it could be either. (Obviously fs.entry must do some work to determine
which it is, so you can optimise slightly by specifying fs.dir / fs.file)

TJG
 
L

Lawrence D'Oliveiro

1. There are far more permission types than just "rwx".

One thing Windows lacks is the ability to replace files that are currently
open by another process. This is why Windows software updates require so
many reboots. On Unix/Linux, you can replace the files, then restart the
affected processes, instead of having to take them down for the entire
duration of the update. This minimizes downtime.
 
L

Lawrence D'Oliveiro

Having this as a separate permission allows normal users to add entries to
log files but not to erase existing entries.

Unix/Linux systems can do this already.
 
N

Nobody

Ooh, I didn't know that -- what combination of permissions would I have to
use to get such an effect?

You can't do it with permissions, you need to use ext2 attributes.
Specifically, "chattr +a <filename>" will set the "append" attribute,
which prevents the file being opened for write except in append mode.
Changing this attribute requires root privilege or the CAP_LINUX_IMMUTABLE
capability.
 
L

Lawrence D'Oliveiro

Rami said:
Ooh, I didn't know that -- what combination of permissions would I
have to use to get such an effect?

No special permissions needed at all—just use the syslog(3) functions.

And the nice thing is, you don’t have to know whether the system logs are
kept on the local machine or on a remote machine, or how different
categories of messages are divided up into different files, how log rotation
is done, or anything like that—it’s all transparent.
 
L

Lawrence D'Oliveiro

Tim Golden said:
Can you run Python from within a Run-As-Administrator command
prompt?

Kind of worrying, isn’t it, when the answer to “my program won’t work†is
“give it more privileges� Defeats the point of having such a complex
security system, doesn’t it, when people are no longer able to understand
its ramifications, and have to resort to bypassing it to get work done?
 
R

Rami Chowdhury

You can't do it with permissions, you need to use ext2 attributes.
Specifically, "chattr +a <filename>" will set the "append" attribute,
which prevents the file being opened for write except in append mode.
Changing this attribute requires root privilege or the CAP_LINUX_IMMUTABLE
capability.

Fascinating, thank you!
 
R

Rami Chowdhury

No special permissions needed at all—just use the syslog(3) functions.

And the nice thing is, you don’t have to know whether the system logs are
kept on the local machine or on a remote machine, or how different
categories of messages are divided up into different files, how log rotation
is done, or anything like that—it’s all transparent.

Ah, thanks -- I think I'd misread your first post as indicating that
that kind of "append" effect would work for any file. Apologies for
the misunderstanding!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,600
Members
45,180
Latest member
CryptoTax Software
Top