A follow-up on the last post
January 15, 2010
I’ve done very little non-hobbyist Unix programming. I’ve been writing code for various Microsoft platforms professionally for over 20 years now. I have a far better understanding of the Unix security model.
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)