Given a username, password and domain, confirm that the user has the right to log on to the current machine. This can generally be used as way of having a non-logged-on user type their usual Windows credentials into a dialog box and confirming them against the usual security database.
The traditional way, which I shall be highlighting here, is to use the LogonUser API exposed by the win32security module in pywin32. The more modern, but also more complex alternative is the SSPI interface, also exposed by pywin32 but not discussed here. Sorry.
This API's intended use is to give you back a token which can be use to open a process as that user, doing the kind of thing which the RunAs commandline tool does. We're using it here for the simpler purpose of confirming that the active security provider will accept the combination of domain, username and password.
The right to call the function, though, is tied to the "Act as part of the Operating System" privilege. To grant every logged on user that right solely so an application they run can authenticate other users is a little risky. The recommended technique is to use this call in a separate, privileged process (perhaps a service) to which the calling application would pass credentials.
import getpass import win32security domain = raw_input ("Domain: ") username = raw_input ("Username: ") password = getpass.getpass ("Password: ") try: hUser = win32security.LogonUser ( username, domain, password, win32security.LOGON32_LOGON_NETWORK, win32security.LOGON32_PROVIDER_DEFAULT ) except win32security.error: print "Failed" else: print "Succeeded"
# # For simplicity, I've used a Pyro object # (from http://pyro.sf.net) without a # nameserver. Obviously, this doesn't # have to be on the local machine. # import win32security import Pyro.core class LogonServer (Pyro.core.ObjBase): def __init__ (self): Pyro.core.ObjBase.__init__(self) def is_user_valid (self, username, password, domain=None): try: print "Checking", username hUser = win32security.LogonUser ( username, domain, password, win32security.LOGON32_LOGON_NETWORK, win32security.LOGON32_PROVIDER_DEFAULT ) except win32security.error: return False else: return True daemon = Pyro.core.Daemon () daemon.connect (LogonServer (), "LogonServer") daemon.requestLoop ()
import Pyro.core import getpass logon_server = Pyro.core.getProxyForURI ("PYROLOC://localhost/LogonServer") while True: domain = raw_input ("Domain: ") username = raw_input ("Username: ") password = getpass.getpass ("Password: ") if logon_server.is_user_valid (username, password, domain): print "OK" else: print "Failed"