[英]Taking directory ownership on Windows with Python results in “Access denied” error
我正在尝试使用以下代码获取目录的所有权:
sd = win32security.SECURITY_DESCRIPTOR()
sd.SetSecurityDescriptorOwner(curUser, False)
win32security.SetFileSecurity("C:/ProgramData/Test",
win32security.OWNER_SECURITY_INFORMATION, sd)
SetFileSecurity
调用失败并显示“拒绝访问”错误。
当前用户的访问权限已从此目录中删除。 在资源管理器中我可以看到它,但是当我尝试打开它时,我首先必须以管理员身份取得所有权。 这在资源管理器中有效,但上面的代码是使用提升的权限执行的,并且由于某种原因它仍然失败。 有什么建议?
您可以通过启用SeTakeOwnerShipPrivilege
强行取得所有权,但当然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
我基于 Eryk 的工作为 Windows 下的 NTFS 文件制作了完整的递归 ACL 和 onwership 处理路由: https ://stackoverflow.com/a/61041460/2635443
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.