How to test if a user is an adminstrator in Python

January 15, 2010

Note that you can’t just test for membership in the “administrators” group, or your code will fail if you run it in a non-english-speaking country (where “administrators” may be “Administrateurs”).

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

    See MSDN entry here: http://msdn.microsoft.com/en-us/library/aa376389(VS.85).aspx
    """
    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)
Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.