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"