Does Python 3 Have Ldap Module?
Solution 1:
You may use ldap3 module (formerly known as python3-ldap), it runs on python3 really well and requires no external C dependances. Also it can correctly handle both unicode and byte data in ldap records (in early versions there was a trouble with jpegPhoto field, now everything is fine)
Solution 2:
If you're running this on Windows, you can get LDAP to work in Python 3.1 by using the ADO access method via Mark Hammond's PyWin32.
To test this, I installed ActiveState Python 3.1, then installed PyWin32 for Python 3.1
http://sourceforge.net/projects/pywin32/files/
I was then able to run LDAP queries using a module I wrote that is based on this LDAP code from the ActiveState Python Cookbook:
Recipe 511451: Dump all Active Directory Information using LDAP scripting by Manuel Garcia
http://code.activestate.com/recipes/511451/
although now that I look at it I realize I completely rewrote my module just using his code as an example.
Update
Here is my LDAPList module and another support module to convert user access bit codes into something a tiny bit more english-like:
LDAPList.py
# LDAPList.py# Todd Fiske# class to encapsulate accessing LDAP information# 2009-03-18 first version# 2010-01-04 updated for Python 3 (print functions, <> to !=)import win32com.client
import UACCodes
ADS_SCOPE_SUBTREE = 2classLDAPList():
def__init__(self, sContext):
self.Context = sContext # naming context, "DC=xyz,DC=org"
self.objectCategory = ""
self.objectClass = ""
self.FilterClause = ""
self.query = ""
self.cn = None
self.cm = None
self.rs = NonedefSetCategory(self, sCategory):
self.objectCategory = sCategory
self.FilterClause = "where objectCategory = '%s'" % self.objectCategory
defSetClass(self, sClass):
self.objectClass = sClass
self.FilterClause = "where objectClass = '%s'" % self.objectClass
defopen(self):
self.query = "select * from 'LDAP://%s' %s order by displayName" % (self.Context, self.FilterClause)
self.cn = win32com.client.Dispatch("ADODB.Connection")
self.cm = win32com.client.Dispatch("ADODB.Command")
self.cn.Open("Provider=ADsDSOObject")
self.cm.ActiveConnection = self.cn
self.cm.Properties["Page Size"] = 1000
self.cm.Properties["Searchscope"] = ADS_SCOPE_SUBTREE
self.cm.CommandText = self.query
self.rs = self.cm.Execute()[0]
defclose(self):
if self.rs isnotNone:
self.rs.Close()
self.rs = Noneif self.cm isnotNone:
self.cm = Noneif self.cn isnotNone:
self.cn.Close()
self.cn = Nonedefcount(self):
if self.rs isNone:
return -2return self.rs.RecordCount
defmore(self):
if self.rs isNone:
returnFalsereturnnot self.rs.EOF
defGetObject(self):
if self.rs isNone:
returnNonereturn win32com.client.GetObject(self.rs.Fields["ADsPath"].Value)
defnext(self):
if self.rs isNone:
return
self.rs.MoveNext()
#----------# helper functionsdefNamingContext():
# return default naming context
root = win32com.client.GetObject("LDAP://RootDse")
return root.get("DefaultNamingContext")
defAccountControl(obj):
if obj.userAccountControl isnotNone:
return obj.userAccountControl
else:
return0defConvertUAC(nUAC):
return UACCodes.ConvertUAC(nUAC)
defAccountActive(n):
return (n & UACCodes.ADS_UF_ACCOUNTDISABLE) != UACCodes.ADS_UF_ACCOUNTDISABLE
defGetCategory(obj):
# CN=Group,CN=Schema,CN=Configuration,DC=xyz,DC=org
s = obj.objectCategory
s = s.split(",")[0][3:]
return s
# s = "Group"defGetGroups(obj):
"""
('CN=XYZ Staff Rockville,OU=Distribution Groups,DC=xyz,DC=org',
'CN=XYZ Staff,OU=Distribution Groups,DC=xyz,DC=org')
"""if obj.memberOf isNone:
return""iftype(obj.memberOf)==type(()):
tGroups = obj.memberOf
else:
tGroups = (obj.memberOf,)
return tGroups
defGetNameParts(obj):
if obj.givenName isNone:
sFirst = ""else:
sFirst = obj.givenName
if obj.middleName isNone:
sMiddle = ""else:
sMiddle = obj.middleName
if obj.sn isNone:
sLast = ""else:
sLast = obj.sn
if sLast == ""and sFirst == "":
if obj.name isnotNone:
sName = obj.name
sName = sName[3:]
lParts = sName.split(" ")
iflen(lParts) == 1:
"todo: split on embedded capital letter"print("single-part name: %s" % sName)
sFirst = sName
else:
sLast = lParts[-1]
sFirst = " ".join(lParts[:-1])
return (sFirst, sMiddle, sLast)
defGetManager(obj):
if obj.manager isNone:
return""else:
return obj.manager
#----------# testif __name__ == "__main__":
printprint("testing LDAPList class")
nc = NamingContext()
print("context =", nc)
ll = LDAPList(nc)
ll.SetCategory('user')
ll.open() # generates recordsetprint("query = %s" % ll.query)
print("%d items" % ll.count())
n = 0while (n < 10) and (ll.more()):
o = ll.GetObject() # return
nUAC = AccountControl(o)
print("%-30s %-30s %-30s %-40s %s" % (
o.displayName,
o.name,
o.sAMAccountName,
UACCodes.ConvertUAC(nUAC),
GetManager(o)
))
n += 1
ll.next()
ll.close()
###
UACCodes.py
# UACCodes.py# Todd Fiske# generated 2009-09-23 16:36:56 by BuildUACCodes.py# updated 2010-01-04 for Python 3 (print functions)# provide UAC constants, lookup list, and conversion function
import sys
# UAC Constants
ADS_UF_SCRIPT = 0x00000001
ADS_UF_ACCOUNTDISABLE = 0x00000002
ADS_UF_HOMEDIR_REQUIRED = 0x00000008
ADS_UF_LOCKOUT = 0x00000010
ADS_UF_PASSWD_NOTREQD = 0x00000020
ADS_UF_PASSWD_CANT_CHANGE = 0x00000040
ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x00000080
ADS_UF_TEMP_DUPLICATE_ACCOUNT = 0x00000100
ADS_UF_NORMAL_ACCOUNT = 0x00000200
ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = 0x00000800
ADS_UF_WORKSTATION_TRUST_ACCOUNT = 0x00001000
ADS_UF_SERVER_TRUST_ACCOUNT = 0x00002000
ADS_UF_DONT_EXPIRE_PASSWD = 0x00010000
ADS_UF_MNS_LOGON_ACCOUNT = 0x00020000
ADS_UF_SMARTCARD_REQUIRED = 0x00040000
ADS_UF_TRUSTED_FOR_DELEGATION = 0x00080000
ADS_UF_NOT_DELEGATED = 0x00100000
ADS_UF_USE_DES_KEY_ONLY = 0x00200000
ADS_UF_DONT_REQUIRE_PREAUTH = 0x00400000
ADS_UF_PASSWORD_EXPIRED = 0x00800000
ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x01000000
# UAC short name lookup list
lUACCodes = [
("ADS_UF_SCRIPT" , 0x00000001, "script"),
("ADS_UF_ACCOUNTDISABLE" , 0x00000002, "disabled"),
("ADS_UF_HOMEDIR_REQUIRED" , 0x00000008, "homedir"),
("ADS_UF_LOCKOUT" , 0x00000010, "lockout"),
("ADS_UF_PASSWD_NOTREQD" , 0x00000020, "pwnotreqd"),
("ADS_UF_PASSWD_CANT_CHANGE" , 0x00000040, "pwcantchange"),
("ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED" , 0x00000080, "encryptedpw"),
("ADS_UF_TEMP_DUPLICATE_ACCOUNT" , 0x00000100, "dupaccount"),
("ADS_UF_NORMAL_ACCOUNT" , 0x00000200, "useracct"),
("ADS_UF_INTERDOMAIN_TRUST_ACCOUNT" , 0x00000800, "interdomain"),
("ADS_UF_WORKSTATION_TRUST_ACCOUNT" , 0x00001000, "workstation"),
("ADS_UF_SERVER_TRUST_ACCOUNT" , 0x00002000, "server"),
("ADS_UF_DONT_EXPIRE_PASSWD" , 0x00010000, "pwnoexpire"),
("ADS_UF_MNS_LOGON_ACCOUNT" , 0x00020000, "mnslogon"),
("ADS_UF_SMARTCARD_REQUIRED" , 0x00040000, "smartcard"),
("ADS_UF_TRUSTED_FOR_DELEGATION" , 0x00080000, "trustdeleg"),
("ADS_UF_NOT_DELEGATED" , 0x00100000, "notdeleg"),
("ADS_UF_USE_DES_KEY_ONLY" , 0x00200000, "deskey"),
("ADS_UF_DONT_REQUIRE_PREAUTH" , 0x00400000, "nopreauth"),
("ADS_UF_PASSWORD_EXPIRED" , 0x00800000, "pwexpired"),
("ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION", 0x01000000, "trustauth"),
]
# UAC conversion function
def ConvertUAC(nUAC):
s = ""
for c in lUACCodes:
if ((nUAC & c[1]) == c[1]):
s = s + c[2] + " "
return s
# test routine
if __name__ == "__main__":
print("UACCodes Test")
print("-------------")
for n in [0, 512, 514, 65535]:
print("%d = %s" % (n, ConvertUAC(n)))
print
for s in sys.argv[1:]:
n = int(s)
print("%d = %s" % (n, ConvertUAC(n)))
###
Both modules have some usage examples and should be fairly easy to figure out, but let me know if you have any questions or comments.
Solution 3:
There is a Pure Python implementation of an LDAP client called Ldaptor. I don't think it's maintained though. If you really need it, you might be able to run 2to3 on this and port it.
Solution 4:
This answer is no longer accurate; see below for other answers.
Sorry to break this on you, but I don't think there is a python-ldap
for Python 3 (yet)...
That's the reason why we should keep active development at Python 2.6 for now (as long as most crucial dependencies (libs) are not ported to 3.0).
Post a Comment for "Does Python 3 Have Ldap Module?"