Reputation: 26129
I don't know much about AD and LDAP, but trying to implement the most trivial LDAP/AD login function in Python. Lo luck so far though I tested several different modules. The most promising one might be ldap3:
>>> import ldap3
>>> server = ldap3.Server('myserver')
>>> connection = ldap3.Connection(server)
>>> connection.bind()
True
>>> connection.search(search_base='DC=mydomain,DC=com', search_filter='(&(objectClass=person)([email protected]))', search_scope='LEVEL', attributes=ldap3.ALL_ATTRIBUTES)
True
>>> connection.response[0]
{'uri': ['ldap://ForestDnsZones.mydomain.com/DC=ForestDnsZones,DC=mydomain,DC=com??base'], 'type': 'searchResRef'}
>>> connection.result
{'result': 0, 'description': 'success', 'dn': '', 'message': '', 'referrals': None, 'type': 'searchResDone'}
Could you give me some pointers if this is on the right path or not?
The setup seems good enough for the basics, as I'm able to extract some type of metadata from it:
>>> server._get_dsa_info(connection)
>>> server._dsa_info
DSA info (from DSE):
Supported LDAP versions: 3, 2
Naming contexts:
DC=mydomain,DC=com
CN=Configuration,DC=mydomain,DC=com
CN=Schema,CN=Configuration,DC=mydomain,DC=com
DC=DomainDnsZones,DC=mydomain,DC=com
DC=ForestDnsZones,DC=mydomain,DC=com
Supported controls:
1.2.840.113556.1.4.1338 - Verify name - Control - MICROSOFT
1.2.840.113556.1.4.1339 - Domain scope - Control - MICROSOFT
1.2.840.113556.1.4.1340 - Search options - Control - MICROSOFT
...
I've also tried flask-ldap3-login, but is starting to suspect that our AD is not configured according to standard, as I'm getting:
...
>>> response = ldap_manager.authenticate('me', 'my_pass')
LDAPNoSuchObjectResult - 32 - noSuchObject - CN=Schema,CN=Configuration,DC=mydomain,DC=com - 0000208D: NameErr: DSID-0315270B, problem 2001 (NO_OBJECT), data 0, best match of:
'CN=Schema,CN=Configuration,DC=mydomain,DC=com'
- searchResDone - None
Please don't hesitate to ask for additional information, and I'll try to figure it out as best I can. For instance, my own user is located in:
CN=Lastname Firstname,OU=Consultants,OU=Users,OU=SE,OU=MYDOMAIN,DC=mydomain,DC=com
Some values are:
objectClass = top;person;organizationalPerson;user
name = Lastname Firstname
userPrincipalName = [email protected]
Also, from CN=Schema,CN=Configuration,DC=mydomain,DC=com
there is only one subschema, which is CN=Aggregate,CN=Schema,CN=Configuration,DC=mydomain,DC=com
and it looks empty. For some reason I believe this is what flask-ldap3-login tries to use.
Upvotes: 4
Views: 5932
Reputation: 26129
My problem using the ldap3.Connection
was that I didn't use a login when binding. This seems to be a way forward:
import ldap3
user = '[email protected]'
password = 'mypassword'
server = ldap3.Server('myserver')
connection = ldap3.Connection(server, user=user, password=password)
connection.bind()
connection.search(search_base='DC=mycompany,DC=com', search_filter='(&(objectClass=user)(userPrincipalName='+user+'))', search_scope='SUBTREE', attributes='*')
And if you like to print some data:
attrs = connection.response[0]['attributes']
print(attrs['displayName'])
for memb in attrs['memberOf']:
print(memb.partition('=')[2].partition(',')[0])
Upvotes: 4