在Windows上使用Python获取目录所有权会导致“访问被拒绝".错误 [英] Taking directory ownership on Windows with Python results in "Access denied" error

查看:259
本文介绍了在Windows上使用Python获取目录所有权会导致“访问被拒绝".错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过以下代码获得目录的所有权:

I'm trying to take ownership of a directory with the following code:

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

SetFileSecurity调用失败,并显示访问被拒绝"错误.

The SetFileSecurity call fails with an "Access denied" error.

当前用户的访问权限已从此目录中删除.在资源管理器中,我可以看到它,但是当我尝试打开它时,我首先必须拥有管理员身份.那在资源管理器中有效,但是上面的代码是使用提升的权限执行的,由于某种原因,它仍然会失败.有什么建议吗?

The access rights for the current user have been removed from this directory. In Explorer I can see it, but when I try to open it, I first have to take ownership as an administrator. That works in Explorer, but the above code is executed with elevated permissions, and for some reason it still fails. Any suggestions?

推荐答案

您可以通过启用SeTakeOwnerShipPrivilege来强制获得所有权,但前提是您的访问令牌必须具有此特权(例如,高级管理员).另外,您可以通过启用SeRestorePrivilege来将所有权强制分配给另一个安全主体,例如SYSTEM.如果没有后者,则分配可能会失败,并显示错误代码ERROR_INVALID_OWNER.

You can forcefully take ownership by enabling SeTakeOwnerShipPrivilege, but of course only if your access token has this privilege (e.g. an elevated administrator). Also, you can forcefully assign ownership to another security principal, such as SYSTEM, by enabling SeRestorePrivilege. Without the latter, the assignment may fail with the error code ERROR_INVALID_OWNER.

以下set_file_owner函数具有force选项,该选项试图临时启用这两个特权.

The following set_file_owner function has a force option that attempts to temporarily enable both of these privileges.

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

这篇关于在Windows上使用Python获取目录所有权会导致“访问被拒绝".错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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