python-ldap vs. Active directory

Jason Tishler jason at tishler.net
Fri May 20 18:20:44 CEST 2005


Sean,

On Thu, May 19, 2005 at 03:24:13PM -0700, Sean O'Connell wrote:
> I am trying to get a trivial python-ldap script to work talking to our
> campus active directory from a Linux machine (Fedora Core 3 or Centos
> 4), but I am being thwarted. I have successfully used python-ldap
> (same versions) to talk to an openldap server quite happily; however,
> the AD servers are proving to be quite stubborn.

I had trouble when my company switched to AD (i.e., MS Exchange 2000)
from MS Exchange 5.5 too.  Hopefully, the attached script will give you
some ideas to try.  FWIW, it works for me from mutt.

Jason

-- 
PGP/GPG Key: http://www.tishler.net/jason/pubkey.asc or key servers
Fingerprint: 7A73 1405 7F2B E669 C19D  8784 1AFD E4CC ECF4 8EF6
-------------- next part --------------
#!/usr/bin/env python

# $Id: MuttLdapQuery.py,v 1.10 2005/04/13 20:24:18 jtishler Exp $

import sys, ldap, string, re, os.path

def MakeAlias(anEntry):
	aName, aOu = FixName(anEntry[1]['displayName'][0])
	aMail = 'unavailable'
	if anEntry[1].has_key('mail') and anEntry[1]['mail']:
		aMail = GetMailAddress(anEntry[1]['mail'])
	anAlias = '%(aMail)s\t%(aName)s\t%(aOu)s' % vars()
	return anAlias

def GetMailAddress(aMails):
	anAddress = aMails[0]
	for aMail in aMails:
		if string.find(aMail, '_') == -1:
			anAddress = aMail
			break
	return anAddress

def FixName(name):
	full = r'([^,]+), (.+) \((.+)\)'
	full2 = r'([^,]+), (.+)\((.+)\)'
	partial = r'([^,]+), (.+)'

	m = re.match(full, name)
	if not m:
		m = re.match(full2, name)
	if not m:
		m = re.match(partial, name)

	if m and len(m.groups()) >= 2:
		first = string.strip(m.group(2))
		last = string.strip(m.group(1))
		name = first + ' ' + last
	org = ''
	if m and len(m.groups()) == 3:
		org = m.group(3)
	return name, org

theLdapHost = 'ad.foo.com'  # *** CHANGE ME ***
theLdapPort = 3268
theLdapUser = 'domain\user' # *** CHANGE ME ***
theLdapPassword = file(os.path.expanduser('~/.passwd')).read()[:-1]
theBase = 'dc=foo,dc=com'   # *** CHANGE ME ***
theScope = ldap.SCOPE_SUBTREE
theFilter = '(&(displayName=%(aQuery)s*)(mailNickname=*))'
theAttributes = ('displayName', 'mail', 'ou')

theFoundMessage = 'Found %(aNumEntries)d matching entries on %(theLdapHost)s:'
theNotFoundMessage = 'Found no matching entries on %(theLdapHost)s'
theErrorMessage = 'LDAP search to %(theLdapHost)s failed'

aQuery = sys.argv[1]
aFilter = theFilter % vars()

try:
	aLdapHost = ldap.open(theLdapHost, theLdapPort)
	aLdapHost.simple_bind(theLdapUser, theLdapPassword)
	anEntries = aLdapHost.search_s(theBase, theScope, aFilter, theAttributes)
	if anEntries:
		aNumEntries = len(anEntries)
		print theFoundMessage % vars()
		for anEntry in anEntries:
			print MakeAlias(anEntry)
		aStatus = 0
	else:
		print theNotFoundMessage % vars()
		aStatus = 1
except:
	print theErrorMessage % vars()
	aStatus = 2

sys.exit(aStatus)


More information about the python-ldap mailing list