我正在尋找一個示例來獲取文件夾ACL權限與Python 27。 我需要的結果是這樣的:domain \ username - FullControl,domain \ username修改Python - 獲取windows文件夾的ACL權限
謝謝!
我正在尋找一個示例來獲取文件夾ACL權限與Python 27。 我需要的結果是這樣的:domain \ username - FullControl,domain \ username修改Python - 獲取windows文件夾的ACL權限
謝謝!
這是WMI使用Tim Golden的例子wmi module。它爲給定的路徑選擇一個Win32_LogicalFileSecuritySetting
的實例。它調用GetSecurityDescriptor
方法得到Win32_SecurityDescriptor
。我用這個來創建Ace
和FileSecurity
命名的多個實例。我已經添加了一些方法來測試ACE授予,拒絕或審計的訪問權限,並以與icacls使用類似的格式輸出數據。
我還包括ctypes代碼來啓用SeSecurityPrivilege
,這是讀取系統訪問控制列表(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' %
'\n '.join(str(x) for x in self.dacl)]
if self.sacl:
items += ['SACL: %s' %
'\n '.join(str(x) for x in self.sacl)]
return '\n'.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
。下面是一些ctypes的代碼以使特權:
例如,我添加了一個審計ACE到「Program Files」目錄記錄不會有任何人試圖改變目錄的權限或所有者。此ACE類型存儲在系統訪問控制列表(SACL)中。
>>> enable_privilege('SeSecurityPrivilege')
>>> print get_file_security('C:\\Program Files')
Path : C:\Program Files
Owner: NT SERVICE\TrustedInstaller
Group: NT SERVICE\TrustedInstaller
DACL : NT SERVICE\TrustedInstaller:(F)
NT SERVICE\TrustedInstaller:(CI)(IO)(F)
NT AUTHORITY\SYSTEM:(M)
NT AUTHORITY\SYSTEM:(OI)(CI)(IO)(F)
BUILTIN\Administrators:(M)
BUILTIN\Administrators:(OI)(CI)(IO)(F)
BUILTIN\Users:(RX)
BUILTIN\Users:(OI)(CI)(IO)(RX)
CREATOR OWNER:(OI)(CI)(IO)(F)
APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(RX)
APPLICATION PACKAGE AUTHORITY\ALL 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\tempfile
Owner: BUILTIN\Administrators
Group: THISPC\None
DACL : BUILTIN\Guests:(DENY)(M)
BUILTIN\Administrators:(I)(F)
NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Users:(I)(RX)
NT AUTHORITY\Authenticated Users:(I)(M)
謝謝。但是有沒有簡單的方法可以做到這一點?這個例子對於這樣一個簡單的任務看起來相當複雜 –
如果你正在編寫一個程序來從頭開始,使用wmi是最簡單的方法。我本來可以通過ctypes使用Windows API來完成所有的工作,但是這會更長。如果你只是想要文本輸出,使用子進程調用icacls.exe並轉儲DACL將會簡單很多,但是(1)通常不是很有用,(2)它是Stack Overflow的主題;這是[超級用戶](http://superuser.com)的主題。 – eryksun