使用Python获取Windows上的目录所有权会导致“访问被拒绝”错误

我试图采取以下代码的目录的所有权:

sd = win32security.SECURITY_DESCRIPTOR() sd.SetSecurityDescriptorOwner(curUser, False) win32security.SetFileSecurity("C:/ProgramData/Test", win32security.OWNER_SECURITY_INFORMATION, sd) 

SetFileSecurity调用失败,出现“访问被拒绝”错误。

当前用户的访问权限已从该目录中删除。 在资源pipe理器中,我可以看到它,但是当我尝试打开它时,我首先必须以pipe理员身份拥有所有权。 这在Explorer中工作,但上面的代码是用提升的权限执行的,出于某种原因它仍然失败。 有什么build议么?

您可以通过启用SeTakeOwnerShipPrivilege来强制拥有所有权,但是当然只有当您的访问令牌具有此权限(例如,高级管理员)时。 另外,通过启用SeRestorePrivilege ,您可以强制将所有权分配给另一个安全主体,如SYSTEM 。 没有后者,分配可能会失败,错误代码为ERROR_INVALID_OWNER

以下set_file_owner函数有一个force选项,试图暂时启用这两个特权。

 import win32api import win32security def set_file_owner(path, sid=None, force=False): try: hToken = win32security.OpenThreadToken(win32api.GetCurrentThread(), win32security.TOKEN_ALL_ACCESS, True) except win32security.error: hToken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), win32security.TOKEN_ALL_ACCESS) if sid is None: sid = win32security.GetTokenInformation(hToken, win32security.TokenOwner) prev_state = () if force: new_state = [(win32security.LookupPrivilegeValue(None, name), win32security.SE_PRIVILEGE_ENABLED) for name in (win32security.SE_TAKE_OWNERSHIP_NAME, win32security.SE_RESTORE_NAME)] prev_state = win32security.AdjustTokenPrivileges(hToken, False, new_state) try: sd = win32security.SECURITY_DESCRIPTOR() sd.SetSecurityDescriptorOwner(sid, False) win32security.SetFileSecurity(path, win32security.OWNER_SECURITY_INFORMATION, sd) finally: if prev_state: win32security.AdjustTokenPrivileges(hToken, False, prev_state) def get_file_owner(path): sd = win32security.GetFileSecurity(path, win32security.OWNER_SECURITY_INFORMATION) sid = sd.GetSecurityDescriptorOwner() return win32security.LookupAccountSid(None, sid) 

 if __name__ == '__main__': import os import tempfile import subprocess username = os.environ['UserName'] test_path = tempfile.mkdtemp() print('Test path: {}'.format(test_path)) subprocess.call(['icacls.exe', test_path, '/setowner', 'SYSTEM'], creationflags=8) owner = get_file_owner(test_path) print('Initial owner: {}\\{}'.format(owner[1], owner[0])) try: print('Denying write owner access') subprocess.call(['icacls.exe', test_path, '/deny', '{}:(WO)'.format(username)], creationflags=8) try: set_file_owner(test_path) except win32security.error: print('Trying with force=True') try: set_file_owner(test_path, force=True) except win32security.error: pass finally: owner = get_file_owner(test_path) print('Final owner: {}\\{}'.format(owner[1], owner[0])) os.rmdir(test_path) 

产量

 Test path: C:\Users\eryksun\AppData\Local\Temp\tmpizgemrdz Initial owner: NT AUTHORITY\SYSTEM Denying write owner access Trying with force=True Final owner: BUILTIN\Administrators