Skip to content

Instantly share code, notes, and snippets.

@chmullig
Last active July 10, 2021 01:53
Show Gist options
  • Save chmullig/127f383addd1e6b74464333aa1f4d2e1 to your computer and use it in GitHub Desktop.
Save chmullig/127f383addd1e6b74464333aa1f4d2e1 to your computer and use it in GitHub Desktop.
Columbia LDAP lookup
Install pyldap (per requirements.py).
Example Usage:
Chris-retina:ldap chmullig$ cat members_head.csv
email
clm2186@columbia.edu
ashutosh.nanda@columbia.edu
Chris-retina:ldap chmullig$ python2.7 ldap_lookup.py members_head.csv
1 []
1 [('uni=an2655,ou=People,o=Columbia University,c=US', {'givenName;x-role-2': ['Ashutosh'], 'cn': ['Ashutosh Nanda'], 'title': ['Student, FU FOUNDATN SCHL OF ENGINEERING & APPLIED SCIENCE:UGRAD'], 'cn;x-role-2': ['Ashutosh Nanda'], 'title;x-role-2': ['Teaching Assistant III'], 'ou;x-role-2': ['Department of Statistics'], 'sn': ['Nanda'], 'uni': ['an2655'], 'sn;x-role-2': ['Nanda'], 'ou': ['Computer Science'], 'givenName': ['Ashutosh']})]
Chris-retina:ldap chmullig$ cat members_head.luldap.csv
email,results,sn,givenName,cn,ou,title,uni
clm2186@columbia.edu,0
ashutosh.nanda@columbia.edu,1,Nanda,Ashutosh,Ashutosh Nanda,Computer Science,"Student, FU FOUNDATN SCHL OF ENGINEERING & APPLIED SCIENCE:UGRAD",an2655
Chris-retina:ldap chmullig$
#ldapsearch -h ldap.columbia.edu -s sub -x -t -b "o=Columbia University,c=US" -LLL "ou=Computer Science"
from paged_search_ext_s import MyLDAPObject
import ldap
import sys
import random
import csv
try:
f = csv.reader(open(sys.argv[1], 'rb'))
head = f.next()
except (KeyError, IOError):
print 'ERROR call with a file to read'
sys.exit(1)
outfn = sys.argv[1][:-4]+'.luldap.csv'
output = csv.writer(open(outfn, "w"))
con = MyLDAPObject("ldap://ldap.columbia.edu")
con.start_tls_s()
dn = "o=Columbia University,c=US"
con.bind_s("", "", ldap.AUTH_SIMPLE)
con.page_size=10
keys = ["sn", "givenName", "cn", "ou", "title", "uni",]
output.writerow(['email', 'results'] + keys)
for (email,) in f:
results_pages, results = con.paged_search_ext_s(
dn,
ldap.SCOPE_SUBTREE,
"(mail=%s)" % (email),
["sn", "givenName", "cn", "ou", "title", "uni",])
print results_pages, results
try:
outrow = [results[0][1].get(key, ['',])[0] for key in keys]
output.writerow([email, len(results)] + outrow)
except:
output.writerow([email, len(results)])
We can make this file beautiful and searchable if this error is corrected: No commas found in this CSV file in line 0.
email
clm2186@columbia.edu
ashutosh.nanda@columbia.edu
We can make this file beautiful and searchable if this error is corrected: It looks like row 2 should actually have 8 columns, instead of 2. in line 1.
email,results,sn,givenName,cn,ou,title,uni
clm2186@columbia.edu,0
ashutosh.nanda@columbia.edu,1,Nanda,Ashutosh,Ashutosh Nanda,Computer Science,"Student, FU FOUNDATN SCHL OF ENGINEERING & APPLIED SCIENCE:UGRAD",an2655
import ldap
from ldap.controls import SimplePagedResultsControl
from ldap.ldapobject import LDAPObject
class PagedResultsSearchObject:
page_size = 10
def paged_search_ext_s(self,base,scope,filterstr='(objectClass=*)',attrlist=None,attrsonly=0,serverctrls=None,clientctrls=None,timeout=-1,sizelimit=0):
"""
Behaves exactly like LDAPObject.search_ext_s() but internally uses the
simple paged results control to retrieve search results in chunks.
This is non-sense for really large results sets which you would like
to process one-by-one
"""
req_ctrl = SimplePagedResultsControl(True,size=self.page_size,cookie='')
# Send first search request
msgid = self.search_ext(
base,
ldap.SCOPE_SUBTREE,
filterstr,
attrlist=attrlist,
serverctrls=(serverctrls or [])+[req_ctrl]
)
result_pages = 0
all_results = []
while True:
rtype, rdata, rmsgid, rctrls = self.result3(msgid)
all_results.extend(rdata)
result_pages += 1
# Extract the simple paged results response control
pctrls = [
c
for c in rctrls
if c.controlType == SimplePagedResultsControl.controlType
]
if pctrls:
if pctrls[0].cookie:
# Copy cookie from response control to request control
req_ctrl.cookie = pctrls[0].cookie
msgid = self.search_ext(
base,
ldap.SCOPE_SUBTREE,
filterstr,
attrlist=attrlist,
serverctrls=(serverctrls or [])+[req_ctrl]
)
else:
break
return result_pages,all_results
class MyLDAPObject(LDAPObject,PagedResultsSearchObject):
pass
### Jaraco's example
# ldap.set_option(ldap.OPT_REFERRALS, 0)
# l = MyLDAPObject(url,trace_level=2)
# l.protocol_version = 3
# l.simple_bind_s("", "")
# l.page_size=10
# # Send search request
# result_pages,all_results = l.paged_search_ext_s(
# base,
# ldap.SCOPE_SUBTREE,
# search_flt,
# attrlist=searchreq_attrlist,
# serverctrls=None
# )
# l.unbind_s()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment