【问题标题】:Check if an arbitrary user is in Administrator Group with Python使用 Python 检查任意用户是否在管理员组中
【发布时间】:2013-03-24 07:45:35
【问题描述】:

有没有办法检查任何给定用户是否在管理员组中?

我知道如何检查 当前 用户是否是管理员,使用:

import ctypes
print ctypes.windll.shell32.IsUserAnAdmin()

但是,如果我以 userA 身份登录,我想知道 userZed 是否具有管理员权限。

任何指针或建议都会有所帮助,我似乎无法找到关于 ctypes.windll.shell32 的任何文档。

【问题讨论】:

    标签: python windows python-2.7 admin ctypes


    【解决方案1】:

    没有真正的方法可以知道给定用户是否具有管理员权限(可能具有域管理员权限,可以是任意组本身的本地管理员组的成员)。 唯一确定的方法是模拟用户,但您需要用户的密码。 成为用户后,您可以检查是否可以写入 system32 文件夹(检查您是否是管理员的简单方法...将注册表项放入 HKLM,然后将其删除。

    如果你只想知道当前用户是否在本地管理员组中,我为此做了一个包,它提供了其中的许多功能

    安装

    pip install windows_tools.users
    

    用法:

    import windows_tools.users as users
    
    # if no user is given, current one is used
    is_admin = is_user_local_admin('myuser')
    print(is_admin)
    

    确保给定用户具有管理员权限的更长答案(仍需要用户密码)

    我的包可以模拟,因此您可能需要通过执行以下操作来检查您是否拥有完整的管理员权限:

    pip install windows_tools.impersonate
    pip install windows_tools.securityprivilege
    

    例子

    import ctypes
    from windows_tools import impersonate
    from windows_tools import users
    from windows_tools import securityprivilege
    
    with impersonate.ImpersonateWin32Sec(
            domain=".", username='someuser', password='somepassword'
        ):
        print(users.whoami())
        try:
            securityprivilege.enable_privilege("SeSecurityPrivilege")
            securityprivilege.disable_privilege("SeSecurityPrivilege")
            print('Yay, I have admin superpowers')
        except ctypes.WinError:
            print('Nope, I am a simple mortal')
    

    【讨论】:

      【解决方案2】:
      import win32net
      
      
      def if_user_in_group(group, member):
          members = win32net.NetLocalGroupGetMembers(None, group, 1)
          return member.lower() in list(map(lambda d: d['name'].lower(), members[0])) 
      
      
      # Function usage
      print(if_user_in_group('SOME_GROUP', 'SOME_USER'))
      

      当然,在您的情况下,“SOME_GROUP”应该是“管理员”

      【讨论】:

        【解决方案3】:

        这是一个包含执行此操作的代码的网站:

        http://skippylovesmalorie.wordpress.com/tag/python-windows/

        我测试了它并且它有效。可以如下使用,注意字符串HAVE必须是unicode否则登录会失败:

        Python 2.7:

        print(user_is_admin(u"johndoe", u"password123", u"MYDOMAIN"))
        

        Python 3.x:

        print(user_is_admin("johndoe", "password123", "MYDOMAIN"))
        

        这是代码,供以后参考:

        import ctypes
        import ctypes.wintypes
        
        def current_user_is_admin():
            return user_token_is_admin(0)
        
        def user_is_admin(username, password, domain=None):
            """note that username, password, and domain should all be unicode"""
        
            LOGON32_LOGON_NETWORK = 3
            LOGON32_PROVIDER_DEFAULT = 0
            token = ctypes.wintypes.HANDLE()
            if ctypes.windll.advapi32.LogonUserW(username, domain, password,
                    LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ctypes.byref(token)) == 0:
                raise Exception("user logon failed")
        
            try:
                return user_token_is_admin(token)
            finally:
                ctypes.windll.kernel32.CloseHandle(token)
        
        
        def user_token_is_admin(user_token):
            """
            using the win32 api, determine if the user with token user_token has administrator rights
            """
            class SID_IDENTIFIER_AUTHORITY(ctypes.Structure):
                _fields_ = [
                    ("byte0", ctypes.c_byte),
                    ("byte1", ctypes.c_byte),
                    ("byte2", ctypes.c_byte),
                    ("byte3", ctypes.c_byte),
                    ("byte4", ctypes.c_byte),
                    ("byte5", ctypes.c_byte),
                ]
            nt_authority = SID_IDENTIFIER_AUTHORITY()
            nt_authority.byte5 = 5
        
            SECURITY_BUILTIN_DOMAIN_RID = 0x20
            DOMAIN_ALIAS_RID_ADMINS = 0x220
            administrators_group = ctypes.c_void_p()
            if ctypes.windll.advapi32.AllocateAndInitializeSid(ctypes.byref(nt_authority), 2,
                SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
                0, 0, 0, 0, 0, 0, ctypes.byref(administrators_group)) == 0:
                raise Exception("AllocateAndInitializeSid failed")
        
            try:
                is_admin = ctypes.wintypes.BOOL()
                if ctypes.windll.advapi32.CheckTokenMembership(
                        user_token, administrators_group, ctypes.byref(is_admin)) == 0:
                    raise Exception("CheckTokenMembership failed")
                return is_admin.value != 0
        
            finally:
                ctypes.windll.advapi32.FreeSid(administrators_group)
        

        【讨论】:

        • 然而,快速的问题,为什么 current_user_is_admin 方法存在?它似乎从未被任何东西使用或调用过。
        • 我认为它只是为了方便。它显示当前用户的 user_token 默认为 0,让您有机会(无需输入当前用户的用户名和密码)逐步完成 ctypes 可能无法实现的“当前用户是否为管理员”功能。 windll.shell32.IsUserAnAdmin().
        猜你喜欢
        • 1970-01-01
        • 2014-05-01
        • 2018-02-02
        • 1970-01-01
        • 2012-12-26
        • 2011-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多