views:

5679

answers:

7

How do I authenticate against AD using Python + LDAP. I'm currently using the python-ldap library and all it is producing is tears.

I can't even bind to perform a simple query:

import sys
import ldap


Server = "ldap://my-ldap-server"
DN, Secret, un = sys.argv[1:4]

Base = "dc=mydomain,dc=co,dc=uk"
Scope = ldap.SCOPE_SUBTREE
Filter = "(&(objectClass=user)(sAMAccountName="+un+"))"
Attrs = ["displayName"]

l = ldap.initialize(Server)
l.protocol_version = 3
print l.simple_bind_s(DN, Secret)

r = l.search(Base, Scope, Filter, Attrs)
Type,user = l.result(r,60)
Name,Attrs = user[0]
if hasattr(Attrs, 'has_key') and Attrs.has_key('displayName'):
  displayName = Attrs['displayName'][0]
  print displayName

sys.exit()

Running this with "[email protected] password username" gives me one of two errors:

Invalid Credentials - When I mistype or intentionally use wrong credentials it fails to authenticate.

ldap.INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 52e, vece', 'desc': 'Invalid credentials'}

Or

ldap.OPERATIONS_ERROR: {'info': '00000000: LdapErr: DSID-0C090627, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, vece', 'desc': 'Operations error'}

What am I missing out to bind properly?

I am getting the same errors on fedora and windows.

+6  A: 

I was missing

l.set_option(ldap.OPT_REFERRALS, 0)

From the init.

1729
I can't tell if this solved your problem.
Johan Buret
I had the same problem, and it solved it for me.
Staale
The root cause of this bug is that you have referrals in the initial response and the windows LDAP code does not send the credentials to the referral server. If you used kerberos credentials it should work.
schlenk
A: 

Use a Distinguished Name to log on your system."CN=Your user,CN=Users,DC=b2t,DC=local" It should work on any LDAP system, including AD

Johan Buret
Nope, it wasn't that.
1729
+2  A: 

If you are open to using pywin32, you can use Win32 calls from Python. This is what we do in our CherryPy web server:

import win32security
token = win32security.LogonUser(
    username,
    domain,
    password,
    win32security.LOGON32_LOGON_NETWORK,
    win32security.LOGON32_PROVIDER_DEFAULT)
authenticated = bool(token)
davidavr
A: 

I see your comment to @Johan Buret about the DN not fixing your problem, but I also believe that is what you should look into.

Given your example, the DN for the default administrator account in AD will be: cn=Administrator,cn=Users,dc=mydomain,dc=co,dc=uk - please try that.

Daniel Bungert
+2  A: 

That worked for me, l.set_option(ldap.OPT_REFERRALS, 0) was the key to access the ActiveDirectory. Moreover, I think that you should add an "con.unbind()" in order to close the connection before finishing the script.

alfredocambera
A: 

If this is part of a webapp intended for authenticated ad-users, this so question might be of interest.

Jan Jungnickel
A: 

I tried to add

l.set_option(ldap.OPT_REFERRALS, 0)

but instead of an error python just hangs and wont respond to anything anymore. Maybe im building the search querry wrong, what is the Base part of the search? Im using the same as the DN for the simple bind (oh and i had to do l.simple_bind, instead of l.simple_bind_s):

import ldap
local = ldap.initialize("ldap://127.0.0.1")
local.simple_bind("CN=staff,DC=mydomain,DC=com")
#my pc is not actually connected to this domain 
result_id = local.search("CN=staff,DC=mydomain,DC=com", ldap.SCOPE_SUBTREE, "cn=foobar", None)
local.set_option(ldap.OPT_REFERRALS, 0)
result_type, result_data = local.result(result_id, 0)

im using AD LDS and the instance is registered for the current account

lanoxx