Python-获取WINDOWS文件夹ACL权限 [英] Python - Get windows folder ACL permissions

查看:0
本文介绍了Python-获取WINDOWS文件夹ACL权限的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一个例子,以获得与Python27的文件夹ACL权限。 我需要这样的结果:域用户名-FullControl,域用户名修改

谢谢!

wmi

以下是使用Tim Golden的wmi module的推荐答案示例。它为给定路径选择Win32_LogicalFileSecuritySetting的实例。它调用GetSecurityDescriptor方法来获取Win32_SecurityDescriptor。我使用它来创建AceFileSecurity命名元组实例。我添加了一些方法来测试ACE授予、拒绝或审核的访问权限,并以类似于ICACLS使用的格式输出数据。

我还包括用于启用SeSecurityPrivilege的ctype代码,这是读取系统访问控制列表(SACL)所必需的。

导入和常量

import os
import wmi
import collections
import ctypes
from ctypes import wintypes

SE_OWNER_DEFAULTED        = 0x0001
SE_GROUP_DEFAULTED        = 0x0002
SE_DACL_PRESENT           = 0x0004
SE_DACL_DEFAULTED         = 0x0008
SE_SACL_PRESENT           = 0x0010
SE_SACL_DEFAULTED         = 0x0020
SE_DACL_AUTO_INHERIT_REQ  = 0x0100
SE_SACL_AUTO_INHERIT_REQ  = 0x0200
SE_DACL_AUTO_INHERITED    = 0x0400
SE_SACL_AUTO_INHERITED    = 0x0800
SE_DACL_PROTECTED         = 0x1000
SE_SACL_PROTECTED         = 0x2000
SE_SELF_RELATIVE          = 0x8000

OBJECT_INHERIT_ACE         = 0x01
CONTAINER_INHERIT_ACE      = 0x02
NO_PROPAGATE_INHERIT_ACE   = 0x04
INHERIT_ONLY_ACE           = 0x08
INHERITED_ACE              = 0x10
SUCCESSFUL_ACCESS_ACE_FLAG = 0x40
FAILED_ACCESS_ACE_FLAG     = 0x80

ACCESS_ALLOWED_ACE_TYPE = 0
ACCESS_DENIED_ACE_TYPE  = 1
SYSTEM_AUDIT_ACE_TYPE   = 2

DELETE                 = 0x00010000 # DE
READ_CONTROL           = 0x00020000 # RC
WRITE_DAC              = 0x00040000 # WDAC
WRITE_OWNER            = 0x00080000 # WO
SYNCHRONIZE            = 0x00100000 # S
ACCESS_SYSTEM_SECURITY = 0x01000000 # AS
GENERIC_READ           = 0x80000000 # GR
GENERIC_WRITE          = 0x40000000 # GW
GENERIC_EXECUTE        = 0x20000000 # GE
GENERIC_ALL            = 0x10000000 # GA

FILE_READ_DATA         = 0x00000001 # RD
FILE_LIST_DIRECTORY    = 0x00000001
FILE_WRITE_DATA        = 0x00000002 # WD
FILE_ADD_FILE          = 0x00000002
FILE_APPEND_DATA       = 0x00000004 # AD
FILE_ADD_SUBDIRECTORY  = 0x00000004
FILE_READ_EA           = 0x00000008 # REA
FILE_WRITE_EA          = 0x00000010 # WEA
FILE_EXECUTE           = 0x00000020 # X
FILE_TRAVERSE          = 0x00000020
FILE_DELETE_CHILD      = 0x00000040 # DC
FILE_READ_ATTRIBUTES   = 0x00000080 # RA
FILE_WRITE_ATTRIBUTES  = 0x00000100 # WA

FILE_GENERIC_READ      = (FILE_READ_DATA        |
                          FILE_READ_EA          |
                          FILE_READ_ATTRIBUTES  |
                          READ_CONTROL          |
                          SYNCHRONIZE)

FILE_GENERIC_WRITE     = (FILE_WRITE_DATA       |
                          FILE_APPEND_DATA      |
                          FILE_WRITE_EA         |
                          FILE_WRITE_ATTRIBUTES |
                          READ_CONTROL          |
                          SYNCHRONIZE)

FILE_GENERIC_EXECUTE    = (FILE_EXECUTE         |
                           FILE_READ_ATTRIBUTES |
                           READ_CONTROL         |
                           SYNCHRONIZE)

FILE_ALL_ACCESS         = 0x001F01FF

FILE_MODIIFY_ACCESS     = FILE_ALL_ACCESS & ~(FILE_DELETE_CHILD |
                                              WRITE_DAC         |
                                              WRITE_OWNER)

FILE_READ_EXEC_ACCESS   = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE

FILE_DELETE_ACCESS      = DELETE | SYNCHRONIZE

_Ace = collections.namedtuple('_Ace',
            'ace_type flags mask mapped_mask sid trustee')

class Ace(_Ace):
    def __new__(cls, ace_type, flags, mask, sid, trustee):
        mapped_mask = cls._map_generic(mask)
        return super(Ace, cls).__new__(cls, ace_type, flags,
                                       mask, mapped_mask, sid, trustee)

    @staticmethod
    def _map_generic(mask):
        if mask & GENERIC_READ:
            mask = (mask & ~GENERIC_READ) | FILE_GENERIC_READ
        if mask & GENERIC_WRITE:
            mask = (mask & ~GENERIC_WRITE) | FILE_GENERIC_WRITE
        if mask & GENERIC_EXECUTE:
            mask = (mask & ~GENERIC_EXECUTE) | FILE_GENERIC_EXECUTE
        if mask & GENERIC_ALL:
            mask = (mask & ~GENERIC_ALL) | FILE_ALL_ACCESS
        return mask

    def inherited(self):         # I
        return bool(self.flags & INHERITED_ACE)
    def object_inherit(self):    # OI
        return bool(self.flags & OBJECT_INHERIT_ACE)
    def container_inherit(self): # CI
        return bool(self.flags & CONTAINER_INHERIT_ACE)
    def inherit_only(self):      # IO
        return bool(self.flags & INHERIT_ONLY_ACE)
    def no_propagate(self):      # NP
        return bool(self.flags & NO_PROPAGATE_INHERIT_ACE)

    def no_access(self):         # N
        return self.mapped_mask == 0
    def full_access(self):       # F
        return self.mapped_mask == FILE_ALL_ACCESS
    def modify_access(self):     # M
        return self.mapped_mask == FILE_MODIIFY_ACCESS
    def read_exec_access(self):  # RX
        return self.mapped_mask == FILE_READ_EXEC_ACCESS
    def read_only_access(self):  # R
        return self.mapped_mask == FILE_GENERIC_READ
    def write_only_access(self): # W
        return self.mapped_mask == FILE_GENERIC_WRITE
    def delete_access(self):     # D
        return self.mapped_mask == FILE_DELETE_ACCESS

    def get_file_rights(self):
        if self.no_access(): return ['N']
        if self.full_access(): return ['F']
        if self.modify_access(): return ['M']
        if self.read_exec_access(): return ['RX']
        if self.read_only_access(): return ['R']
        if self.write_only_access(): return ['W']
        if self.delete_access(): return ['D']
        rights = []
        for right, name in ((DELETE, 'DE'), (READ_CONTROL, 'RC'),
                            (WRITE_DAC, 'WDAC'), (WRITE_OWNER, 'WO'),
                            (SYNCHRONIZE, 'S'),
                            (ACCESS_SYSTEM_SECURITY, 'AS'),
                            (GENERIC_READ, 'GR'), (GENERIC_WRITE, 'GW'),
                            (GENERIC_EXECUTE, 'GE'), (GENERIC_ALL, 'GA'),
                            (FILE_READ_DATA, 'RD'), (FILE_WRITE_DATA, 'WD'),
                            (FILE_APPEND_DATA, 'AD'), (FILE_READ_EA, 'REA'),
                            (FILE_WRITE_EA, 'WEA'), (FILE_EXECUTE, 'X'),
                            (FILE_DELETE_CHILD, 'DC'),
                            (FILE_READ_ATTRIBUTES, 'RA'),
                            (FILE_WRITE_ATTRIBUTES, 'WA')):
            if self.mask & right:
                rights.append(name)
        return rights

    def granted_access(self, mask):
        return bool(self.mapped_mask & self._map_generic(mask))

    def __str__(self):
        trustee = self.trustee if self.trustee else self.sid
        access = []
        if self.ace_type == ACCESS_DENIED_ACE_TYPE:
            access.append('(DENY)')
        elif self.ace_type == SYSTEM_AUDIT_ACE_TYPE:
            access.append('(AUDIT)')
        if self.inherited(): access.append('(I)')
        if self.object_inherit(): access.append('(OI)')
        if self.container_inherit(): access.append('(CI)')
        if self.inherit_only(): access.append('(IO)')
        if self.no_propagate(): acccess.append('(NP)')
        access.append('(%s)' % ','.join(self.get_file_rights()))
        return '%s:%s' % (trustee, ''.join(access))

_FileSecurity = collections.namedtuple('_FileSecurity',
                        'path owner_permissions owner group '
                        'owner_sid group_sid flags dacl sacl')

class FileSecurity(_FileSecurity):
    def __str__(self):
        owner = self.owner if self.owner else self.owner_sid
        group = self.group if self.group else self.group_sid
        items = ['Path:  %s' % self.path,
                 'Owner: %s' % owner,
                 'Group: %s' % group]
        if self.dacl:
            items += ['DACL:  %s' %
                      '
       '.join(str(x) for x in self.dacl)]
        if self.sacl:
            items += ['SACL:  %s' %
                      '
       '.join(str(x) for x in self.sacl)]
        return '
'.join(items)

函数

def list_acl(wmi_acl):
    acl = []
    for entry in wmi_acl:
        trustee = entry.Trustee.Name
        if trustee and entry.Trustee.Domain:
            trustee = '%s\%s' % (entry.Trustee.Domain, trustee)
        mask = entry.AccessMask
        if mask < 0:
            mask += 2 ** 32
        ace = Ace(entry.AceType, entry.AceFlags, mask,
                        entry.Trustee.SIDString, trustee)
        acl.append(ace)
    return acl

# Win32_LogicalFileSecuritySetting
# https://msdn.microsoft.com/en-us/library/aa394180
WQL_LFSS = 'SELECT * FROM Win32_LogicalFileSecuritySetting WHERE Path="%s"'
wmi_ns = wmi.WMI()

def get_file_security(path):
    path = os.path.abspath(path)
    os.stat(path) # ensure path exists
    lfss = wmi_ns.query(WQL_LFSS % (path,))[0]
    sd = lfss.GetSecurityDescriptor()[0]
    owner = sd.Owner.Name
    if owner and sd.Owner.Domain:
        owner = '%s\%s' % (sd.Owner.Domain, owner)
    group = sd.Group.Name
    if group and sd.Group.Domain:
        group = '%s\%s' % (sd.Group.Domain, group)
    dacl = sacl = ()
    if sd.ControlFlags & SE_DACL_PRESENT:
        dacl = tuple(list_acl(sd.DACL))
    if sd.ControlFlags & SE_SACL_PRESENT:
        sacl = tuple(list_acl(sd.SACL))
    return FileSecurity(lfss.Path,
                        lfss.OwnerPermissions,
                        owner, group,
                        sd.Owner.SIDString,
                        sd.Group.SIDString,
                        sd.ControlFlags,
                        dacl, sacl)
访问SACL需要SeSecurityPrivilege。以下是一些启用特权的ctype代码:

kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
advapi32 = ctypes.WinDLL('advapi32', use_last_error=True)

ERROR_NOT_ALL_ASSIGNED = 0x0514
SE_PRIVILEGE_ENABLED = 0x00000002
TOKEN_ALL_ACCESS = 0x000F0000 | 0x01FF

class LUID(ctypes.Structure):
    _fields_ = (('LowPart',  wintypes.DWORD),
                ('HighPart', wintypes.LONG))

class LUID_AND_ATTRIBUTES(ctypes.Structure):
    _fields_ = (('Luid',       LUID),
                ('Attributes', wintypes.DWORD))

class TOKEN_PRIVILEGES(ctypes.Structure):
    _fields_ = (('PrivilegeCount', wintypes.DWORD),
                ('Privileges', LUID_AND_ATTRIBUTES * 1))
    def __init__(self, PrivilegeCount=1, *args):
        super(TOKEN_PRIVILEGES, self).__init__(PrivilegeCount, *args)

PDWORD = ctypes.POINTER(wintypes.DWORD)
PHANDLE = ctypes.POINTER(wintypes.HANDLE)
PLUID = ctypes.POINTER(LUID)
PTOKEN_PRIVILEGES = ctypes.POINTER(TOKEN_PRIVILEGES)

def errcheck_bool(result, func, args):
    if not result:
        raise ctypes.WinError(ctypes.get_last_error())
    return args

kernel32.CloseHandle.argtypes = (wintypes.HANDLE,)

kernel32.GetCurrentProcess.errcheck = errcheck_bool
kernel32.GetCurrentProcess.restype = wintypes.HANDLE

# https://msdn.microsoft.com/en-us/library/aa379295
advapi32.OpenProcessToken.errcheck = errcheck_bool
advapi32.OpenProcessToken.argtypes = (
    wintypes.HANDLE,  # _In_  ProcessHandle
    wintypes.DWORD,   # _In_  DesiredAccess
    PHANDLE)          # _Out_ TokenHandle

# https://msdn.microsoft.com/en-us/library/aa379180
advapi32.LookupPrivilegeValueW.errcheck = errcheck_bool
advapi32.LookupPrivilegeValueW.argtypes = (
    wintypes.LPCWSTR, # _In_opt_ lpSystemName
    wintypes.LPCWSTR, # _In_     lpName
    PLUID)            # _Out_    lpLuid

# https://msdn.microsoft.com/en-us/library/aa375202
advapi32.AdjustTokenPrivileges.errcheck = errcheck_bool
advapi32.AdjustTokenPrivileges.argtypes = (
    wintypes.HANDLE,   # _In_      TokenHandle
    wintypes.BOOL,     # _In_      DisableAllPrivileges
    PTOKEN_PRIVILEGES, # _In_opt_  NewState
    wintypes.DWORD,    # _In_      BufferLength
    PTOKEN_PRIVILEGES, # _Out_opt_ PreviousState
    PDWORD)            # _Out_opt_ ReturnLength

def enable_privilege(privilege):
    hToken = wintypes.HANDLE()
    luid = LUID()
    tp = TOKEN_PRIVILEGES()
    advapi32.LookupPrivilegeValueW(None, privilege, ctypes.byref(luid))
    tp.Privileges[0].Luid = luid
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED
    advapi32.OpenProcessToken(kernel32.GetCurrentProcess(),
                              TOKEN_ALL_ACCESS,
                              ctypes.byref(hToken))
    try:
        advapi32.AdjustTokenPrivileges(hToken, False,
                                       ctypes.byref(tp),
                                       ctypes.sizeof(tp),
                                       None, None)
        if ctypes.get_last_error() == ERROR_NOT_ALL_ASSIGNED:
            raise ctypes.WinError(ERROR_NOT_ALL_ASSIGNED)
    finally:
        kernel32.CloseHandle(hToken)

def disable_privilege(privilege):
    hToken = wintypes.HANDLE()
    luid = LUID()
    tp = TOKEN_PRIVILEGES()
    advapi32.LookupPrivilegeValueW(None, privilege, ctypes.byref(luid))
    tp.Privileges[0].Luid = luid
    tp.Privileges[0].Attributes = 0
    advapi32.OpenProcessToken(kernel32.GetCurrentProcess(),
                              TOKEN_ALL_ACCESS,
                              ctypes.byref(hToken))
    try:
        advapi32.AdjustTokenPrivileges(hToken, False,
                                       ctypes.byref(tp),
                                       ctypes.sizeof(tp),
                                       None, None)
        if ctypes.get_last_error() == ERROR_NOT_ALL_ASSIGNED:
            raise ctypes.WinError(ERROR_NOT_ALL_ASSIGNED)
    finally:
        kernel32.CloseHandle(hToken)
例如,我向"Program Files"目录添加了一个审核ACE,以记录任何人更改该目录的权限或所有者的任何尝试。此ACE类型存储在系统访问控制列表(SACL)中。

>>> enable_privilege('SeSecurityPrivilege')

>>> print get_file_security('C:\Program Files')
Path : C:Program Files
Owner: NT SERVICETrustedInstaller
Group: NT SERVICETrustedInstaller
DACL : NT SERVICETrustedInstaller:(F)
       NT SERVICETrustedInstaller:(CI)(IO)(F)
       NT AUTHORITYSYSTEM:(M)
       NT AUTHORITYSYSTEM:(OI)(CI)(IO)(F)
       BUILTINAdministrators:(M)
       BUILTINAdministrators:(OI)(CI)(IO)(F)
       BUILTINUsers:(RX)
       BUILTINUsers:(OI)(CI)(IO)(RX)
       CREATOR OWNER:(OI)(CI)(IO)(F)
       APPLICATION PACKAGE AUTHORITYALL APPLICATION PACKAGES:(RX)
       APPLICATION PACKAGE AUTHORITYALL APPLICATION PACKAGES:(OI)(CI)(IO)(RX)
SACL : Everyone:(AUDIT)(WDAC,WO)

下面显示拒绝ACE的显示方式:

>>> f = open('tempfile', 'w'); f.close()
>>> os.system('icacls tempfile /deny Guests:(M)')
processed file: tempfile
Successfully processed 1 files; Failed processing 0 files
0
>>> print get_file_security('tempfile')
Path : C:Temp	empfile
Owner: BUILTINAdministrators
Group: THISPCNone
DACL : BUILTINGuests:(DENY)(M)
       BUILTINAdministrators:(I)(F)
       NT AUTHORITYSYSTEM:(I)(F)
       BUILTINUsers:(I)(RX)
       NT AUTHORITYAuthenticated Users:(I)(M)

这篇关于Python-获取WINDOWS文件夹ACL权限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆