gpt4 book ai didi

python - 如何在没有pywin32的情况下使用python确定Windows上的文件所有者

转载 作者:太空狗 更新时间:2023-10-29 21:17:47 32 4
gpt4 key购买 nike

我正在编写一个脚本,它需要确定 Windows 文件所有者的用户名。

虽然我找到了a solution using pywin32但我对使用它犹豫不决,因为我不想添加模块依赖性。

该脚本将为 python 2.6 编写,并且必须在 32 位和 64 位平台上运行。

我想知道是否有不同的方法(可能是使用 ctypes)来确定此信息

最佳答案

下面使用ctypes调用GetNamedSecurityInfo .最初它遵循 code snippet这在问题中有关联,但 GetNamedSecurityInfo 通常比 GetFileSecurity 更有用,特别是因为它与 SetNamedSecurityInfo 配对以代替过时的函数 设置文件安全

ctypes 和类

import ctypes as ctypes
from ctypes import wintypes as wintypes

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

ERROR_INVALID_FUNCTION = 0x0001
ERROR_FILE_NOT_FOUND = 0x0002
ERROR_PATH_NOT_FOUND = 0x0003
ERROR_ACCESS_DENIED = 0x0005
ERROR_SHARING_VIOLATION = 0x0020

SE_FILE_OBJECT = 1
OWNER_SECURITY_INFORMATION = 0x00000001
GROUP_SECURITY_INFORMATION = 0x00000002
DACL_SECURITY_INFORMATION = 0x00000004
SACL_SECURITY_INFORMATION = 0x00000008
LABEL_SECURITY_INFORMATION = 0x00000010

_DEFAULT_SECURITY_INFORMATION = (OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION |
LABEL_SECURITY_INFORMATION)

LPDWORD = ctypes.POINTER(wintypes.DWORD)
SE_OBJECT_TYPE = wintypes.DWORD
SECURITY_INFORMATION = wintypes.DWORD

class SID_NAME_USE(wintypes.DWORD):
_sid_types = dict(enumerate('''
User Group Domain Alias WellKnownGroup DeletedAccount
Invalid Unknown Computer Label'''.split(), 1))

def __init__(self, value=None):
if value is not None:
if value not in self.sid_types:
raise ValueError('invalid SID type')
wintypes.DWORD.__init__(value)

def __str__(self):
if self.value not in self._sid_types:
raise ValueError('invalid SID type')
return self._sid_types[self.value]

def __repr__(self):
return 'SID_NAME_USE(%s)' % self.value

PSID_NAME_USE = ctypes.POINTER(SID_NAME_USE)

class PLOCAL(wintypes.LPVOID):
_needs_free = False
def __init__(self, value=None, needs_free=False):
super(PLOCAL, self).__init__(value)
self._needs_free = needs_free

def __del__(self):
if self and self._needs_free:
kernel32.LocalFree(self)
self._needs_free = False

PACL = PLOCAL

class PSID(PLOCAL):
def __init__(self, value=None, needs_free=False):
super(PSID, self).__init__(value, needs_free)

def __str__(self):
if not self:
raise ValueError('NULL pointer access')
sid = wintypes.LPWSTR()
advapi32.ConvertSidToStringSidW(self, ctypes.byref(sid))
try:
return sid.value
finally:
if sid:
kernel32.LocalFree(sid)

class PSECURITY_DESCRIPTOR(PLOCAL):
def __init__(self, value=None, needs_free=False):
super(PSECURITY_DESCRIPTOR, self).__init__(value, needs_free)
self.pOwner = PSID()
self.pGroup = PSID()
self.pDacl = PACL()
self.pSacl = PACL()
# back references to keep this object alive
self.pOwner._SD = self
self.pGroup._SD = self
self.pDacl._SD = self
self.pSacl._SD = self

def get_owner(self, system_name=None):
if not self or not self.pOwner:
raise ValueError('NULL pointer access')
return look_up_account_sid(self.pOwner, system_name)

def get_group(self, system_name=None):
if not self or not self.pGroup:
raise ValueError('NULL pointer access')
return look_up_account_sid(self.pGroup, system_name)

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

# msdn.microsoft.com/en-us/library/aa376399
advapi32.ConvertSidToStringSidW.errcheck = _check_bool
advapi32.ConvertSidToStringSidW.argtypes = (
PSID, # _In_ Sid
ctypes.POINTER(wintypes.LPWSTR)) # _Out_ StringSid

# msdn.microsoft.com/en-us/library/aa379166
advapi32.LookupAccountSidW.errcheck = _check_bool
advapi32.LookupAccountSidW.argtypes = (
wintypes.LPCWSTR, # _In_opt_ lpSystemName
PSID, # _In_ lpSid
wintypes.LPCWSTR, # _Out_opt_ lpName
LPDWORD, # _Inout_ cchName
wintypes.LPCWSTR, # _Out_opt_ lpReferencedDomainName
LPDWORD, # _Inout_ cchReferencedDomainName
PSID_NAME_USE) # _Out_ peUse

# msdn.microsoft.com/en-us/library/aa446645
advapi32.GetNamedSecurityInfoW.restype = wintypes.DWORD
advapi32.GetNamedSecurityInfoW.argtypes = (
wintypes.LPWSTR, # _In_ pObjectName
SE_OBJECT_TYPE, # _In_ ObjectType
SECURITY_INFORMATION, # _In_ SecurityInfo
ctypes.POINTER(PSID), # _Out_opt_ ppsidOwner
ctypes.POINTER(PSID), # _Out_opt_ ppsidGroup
ctypes.POINTER(PACL), # _Out_opt_ ppDacl
ctypes.POINTER(PACL), # _Out_opt_ ppSacl
ctypes.POINTER(PSECURITY_DESCRIPTOR)) # _Out_opt_ ppSecurityDescriptor

函数

def look_up_account_sid(sid, system_name=None):
SIZE = 256
name = ctypes.create_unicode_buffer(SIZE)
domain = ctypes.create_unicode_buffer(SIZE)
cch_name = wintypes.DWORD(SIZE)
cch_domain = wintypes.DWORD(SIZE)
sid_type = SID_NAME_USE()
advapi32.LookupAccountSidW(system_name, sid, name, ctypes.byref(cch_name),
domain, ctypes.byref(cch_domain), ctypes.byref(sid_type))
return name.value, domain.value, sid_type

def get_file_security(filename, request=_DEFAULT_SECURITY_INFORMATION):
# N.B. This query may fail with ERROR_INVALID_FUNCTION
# for some filesystems.
pSD = PSECURITY_DESCRIPTOR(needs_free=True)
error = advapi32.GetNamedSecurityInfoW(filename, SE_FILE_OBJECT, request,
ctypes.byref(pSD.pOwner), ctypes.byref(pSD.pGroup),
ctypes.byref(pSD.pDacl), ctypes.byref(pSD.pSacl),
ctypes.byref(pSD))
if error != 0:
raise ctypes.WinError(error)
return pSD

示例用法

if __name__ == '__main__':
import os, sys

if len(sys.argv) < 2:
script_name = os.path.basename(__file__)
sys.exit('usage: {} filename'.format(script_name))

filename = sys.argv[1]
if isinstance(filename, bytes):
if hasattr(os, 'fsdecode'):
filename = os.fsdecode(filename)
else:
filename = filename.decode(sys.getfilesystemencoding())

pSD = get_file_security(filename)
owner_name, owner_domain, owner_sid_type = pSD.get_owner()
if owner_domain:
owner_name = '{}\\{}'.format(owner_domain, owner_name)

print("Path : {}".format(filename))
print("Owner: {} ({})".format(owner_name, owner_sid_type))
print("SID : {}".format(pSD.pOwner))

示例输出

Path : C:\Users
Owner: NT AUTHORITY\SYSTEM (WellKnownGroup)
SID : S-1-5-18

Path : C:\ProgramData
Owner: NT AUTHORITY\SYSTEM (WellKnownGroup)
SID : S-1-5-18

Path : C:\Program Files
Owner: NT SERVICE\TrustedInstaller (WellKnownGroup)
SID : S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464

Path : C:\Windows
Owner: NT SERVICE\TrustedInstaller (WellKnownGroup)
SID : S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464

关于python - 如何在没有pywin32的情况下使用python确定Windows上的文件所有者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8086412/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com