How to check directory access attributes (permissions)?

Viewed 165

I need to check access to the directory (permissions for groups) on Windows 8.1 / 10. The bottom line is that a situation is possible where all permissions or part of them are prohibited and, in this case, I do not want to throw expection, and even more so with errno.

It is necessary to understand in advance the function (s) that will show whether I will have WinError or PermissionError when reading/writing, for a specific group or all groups (SYSTEM, Administrator, etc.).

The standard stat library and os.access() did not give me the desired results. There are also options with changing permissions for the directory, but this may not always work, especially in usermode, which is why I try to do the verification.

I also tried to read the rights of the ACL, but nothing came of it because of inexperience.

Such conclusions were drawn from the following code (did I check it exactly like that? I don’t know.), And games with the directory security settings (I also changed the location of the directory to the desktop, my documents, %appdata% and other spaces intended for user data [Everything in C:\Users\% USER_NAME%\]. I thought it might be a mistake.), which always produced the same result (maybe sometimes slightly different, but this does not cancel the question). The most important thing is that an Exception will be thrown if you try to do something with this directory that is not allowed by the rules, and execute in this way:

import os
import stat

def access(path, flag): return os.access(path, flag)
def isExists(path): return access(path, os.F_OK)
def isReadable(path): return access(path, os.R_OK)
def isWritable(path): return access(path, os.W_OK)
def isExecuteable(path): return access(path, os.X_OK)

def mstat(path, followsymlink = 1):
    if isinstance(path, str):
        info = os.stat(path)
        if followsymlink and stat.S_ISLNK(info[stat.ST_MODE]):
            return(os.lstat(path))
        return(info)
    return(os.fstat(path))

def _mode(path): return(mstat(path)[stat.ST_MODE])

def mode(path):   return(stat.S_IMODE(_mode(path)))
def ifreg(path):  return(stat.S_ISREG(_mode(path)))
def ifdir(path):  return(stat.S_ISDIR(_mode(path)))
def ifchr(path):  return(stat.S_ISCHR(_mode(path)))
def ifblk(path):  return(stat.S_ISBLK(_mode(path)))
def iffifo(path): return(stat.S_ISFIFO(_mode(path)))
def iflnk(path):  return(stat.S_ISLNK(_mode(path)))
def ifsock(path): return(stat.S_ISSOCK(_mode(path)))

def is_suid(path):  return(_mode(path) & stat.S_ISUID == stat.S_ISUID)
def is_sgid(path):  return(_mode(path) & stat.S_ISGID == stat.S_ISGID)
def is_svtx(path):  return(_mode(path) & stat.S_ISVTX == stat.S_ISVTX)
def is_read(path):  return(_mode(path) & stat.S_IREAD == stat.S_IREAD)
def is_write(path): return(_mode(path) & stat.S_IWRITE == stat.S_IWRITE)
def is_exec(path):  return(_mode(path) & stat.S_IEXEC == stat.S_IEXEC)
def is_rwxu(path):  return(_mode(path) & stat.S_IRWXU == stat.S_IRWXU)
def is_rusr(path):  return(_mode(path) & stat.S_IRUSR == stat.S_IRUSR)
def is_wusr(path):  return(_mode(path) & stat.S_IWUSR == stat.S_IWUSR)
def is_xusr(path):  return(_mode(path) & stat.S_IXUSR == stat.S_IXUSR)
def is_rwxg(path):  return(_mode(path) & stat.S_IRWXG == stat.S_IRWXG)
def is_rgrp(path):  return(_mode(path) & stat.S_IRGRP == stat.S_IRGRP)
def is_wgrp(path):  return(_mode(path) & stat.S_IWGRP == stat.S_IWGRP)
def is_xgrp(path):  return(_mode(path) & stat.S_IXGRP == stat.S_IXGRP)
def is_rwxo(path):  return(_mode(path) & stat.S_IRWXO == stat.S_IRWXO)
def is_roth(path):  return(_mode(path) & stat.S_IROTH == stat.S_IROTH)
def is_woth(path):  return(_mode(path) & stat.S_IWOTH == stat.S_IWOTH)
def is_xoth(path):  return(_mode(path) & stat.S_IXOTH == stat.S_IXOTH)

path = 'C:\\ERROR_ACCESS_DENIED_SAMPLE'

print(f'''
    mode    = {mode(path)}
    ifreg   = {ifreg(path)}
    ifdir   = {ifdir(path)}
    ifchr   = {ifchr(path)}
    ifblk   = {ifblk(path)}
    iffifo  = {iffifo(path)}
    iflnk   = {iflnk(path)}
    ifsock  = {ifsock(path)}
    is_suid = {is_suid(path)}
    is_sgid = {is_sgid(path)}
    is_svtx = {is_svtx(path)}
    is_read = {is_read(path)}
    is_write = {is_write(path)}
    is_exec = {is_exec(path)}
    is_rwxu = {is_rwxu(path)}
    is_rusr = {is_rusr(path)}
    is_wusr = {is_wusr(path)}
    is_xusr = {is_xusr(path)}
    is_rwxg = {is_rwxg(path)}
    is_rgrp = {is_rgrp(path)}
    is_wgrp = {is_wgrp(path)}
    is_xgrp = {is_xgrp(path)}
    is_rwxo = {is_rwxo(path)}
    is_roth = {is_roth(path)}
    is_woth = {is_woth(path)}
    is_xoth = {is_xoth(path)}
    isExists      = {isExists(path)}
    isReadable    = {isReadable(path)}
    isWritable    = {isWritable(path)}
    isExecuteable = {isExecuteable(path)}
''')

Output:

    mode    = 511
    ifreg   = False
    ifdir   = True
    ifchr   = False
    ifblk   = False
    iffifo  = False
    iflnk   = False
    ifsock  = False
    is_suid = False
    is_sgid = False
    is_svtx = False
    is_read = True
    is_write = True
    is_exec = True
    is_rwxu = True
    is_rusr = True
    is_wusr = True
    is_xusr = True
    is_rwxg = True
    is_rgrp = True
    is_wgrp = True
    is_xgrp = True
    is_rwxo = True
    is_roth = True
    is_woth = True
    is_xoth = True
    isExists      = True
    isReadable    = True
    isWritable    = True
    isExecuteable = True

I would like to see Pure Python as an answer.

1 Answers

the os module does have the os.access function to check access:

os.access('/path/to/folder', os.W_OK) # W_OK is for writing, R_OK for reading, etc.
Related