|
From: Robert S. <ml-...@ep...> - 2002-07-25 08:31:41
|
Hi!
We have been using the Perl Net::LDAP modules to access our directory
server. Now we want to switch to Python. This is a first port of
Net::LDAP::Entry
class Entry:
import ldap
def __init__(self, dn, values = {}):
self.distname = dn
self.values = values
self.chgtype = "add"
self.changes = []
def __str__(self):
return "%s[%s]: %s" % ( self.distname, self.chgtype, self.values )
def get_value(self, attr):
try:
return self.values[attr]
except KeyError, er:
return None
def changetype(self, typ = None):
if typ:
self.chgtype = typ
self.changes = []
else:
return self.chgtype
def dn(self, dn = None):
if dn:
self.distname = dn
else:
return self.distname
def exists(self, attr):
return self.values.has_key(attr)
def add(self, attrs):
if type(attrs) != type([]):
attrs = [attrs]
for typ, val in attrs:
if type(val) != type([]):
val = [val]
if self.values.has_key(typ):
self.values[typ].extend(val)
if self.chgtype == "modify":
self.changes.append((ldap.MOD_REPLACE, typ, self.values[typ]))
else:
self.values[typ] = val
if self.chgtype == "modify":
self.changes.append((ldap.MOD_ADD, typ, val))
def replace(self, attrs):
if type(attrs) != type([]):
attrs = [attrs]
for typ, val in attrs:
if type(val) != type([]):
val = [val]
self.values[typ] = val
if self.chgtype == "modify":
self.changes.append((ldap.MOD_REPLACE, typ, val))
def delete(self, attrs = None):
if attrs:
if type(attrs) != type([]):
attrs = [attrs]
for attr in attrs:
if self.values.has_key(attr):
del(self.values[attr])
if self.chgtype == "modify":
self.changes.append((ldap.MOD_DELETE, attr, None))
def update(self, l):
if self.chgtype == "add":
import ldap.modlist
return l.add_s(self.distname, ldap.modlist.addModlist(self.values))
elif self.chgtype == "delete":
return l.delete_s(self.distname)
elif self.chgtype == "modify":
return l.modify_s(self.distname, self.changes)
You may find it useful.
We have a directory service set up with OpenLDAP extensively using
referrals. It seems that python-ldap currently is not able to handle
these. Is this correct?
Greetings
--
Robert Sander
Manager
Information Systems www.epigenomics.com Kastanienallee 24
+493024345330 10435 Berlin
|
|
From: <mi...@st...> - 2002-07-25 10:10:04
|
Robert Sander wrote: > This is a first port of > Net::LDAP::Entry I have to admit that I do not know Net::LDAP::Entry. Therefore I might not fully understand the rationale. Check out ldap.modlist.modifyModlist(). Simply copy your old entry tweak the new entry's dictionary and create a list you can directly pass to LDAPObject.modify()/modify_s(). In some cases that might not work since there's no smart schema handling of the LDAP syntaxes but most times it's pretty convenient. Ciao, Michael. |
|
From: Robert S. <rob...@ep...> - 2002-07-25 10:15:49
|
On Thu, Jul 25, 2002 at 12:09:06PM +0200, Michael Ströder wrote: > Robert Sander wrote: > >This is a first port of > >Net::LDAP::Entry > > I have to admit that I do not know Net::LDAP::Entry. Therefore I > might not fully understand the rationale. As I wrote we are currently using these Perl modules in our scripts. I ported this class to make the transition easy. Greetings -- Robert Sander Manager Information Systems www.epigenomics.com Kastanienallee 24 +493024345330 10435 Berlin |
|
From: <mi...@st...> - 2002-07-25 22:10:31
|
Robert Sander wrote: > We have a directory service set up with OpenLDAP extensively using > referrals. It seems that python-ldap currently is not able to handle > these. Is this correct? There is support for it. But it's a rather complex topic. Your mileage may vary. Before I write a pile of postings about it I'd like to know what your understanding of handling referrals is. Ciao, Michael. |
|
From: Robert S. <gur...@ep...> - 2002-07-25 10:24:31
|
On Thu, Jul 25, 2002 at 11:59:21AM +0200, Michael Ströder wrote: > Robert Sander wrote: > >We have a directory service set up with OpenLDAP extensively using > >referrals. It seems that python-ldap currently is not able to handle > >these. Is this correct? > > Before I write a pile of postings about it I'd like to know what > your understanding of handling referrals is. The Perl modules in Net::LDAP return a entries array and a references array after a search when the parameter "deref" is set to 3. I think this is DEREF_ALWAYS. With the referrals you are able to search further in the tree. I admit that I haven't tried to use l.deref = ldap.DEREF_ALWAYS and look at the result. Greetings -- Robert Sander Manager Information Systems www.epigenomics.com Kastanienallee 24 +493024345330 10435 Berlin |
|
From: <mi...@st...> - 2002-07-25 10:43:24
|
Robert Sander wrote: > On Thu, Jul 25, 2002 at 11:59:21AM +0200, Michael Str=F6der wrote: >=20 >>Before I write a pile of postings about it I'd like to know what=20 >>your understanding of handling referrals is. >=20 > The Perl modules in Net::LDAP return a entries array and a references > array after a search when the parameter "deref" is set to 3. I think > this is DEREF_ALWAYS. Option OPT_DEREF has nothing to do with referrals. It's for=20 aliases. OPT_REFERRALS is the relevant option which defines=20 whether the OpenLDAP library internally follows referrals or not. > With the referrals you are able to search further in the tree. If you switch off internal referral handling you will receive=20 search continuations along with normal search results as tuples=20 with None as first item and a string containing the LDAP URL as=20 second item. (Note that it might block when python-ldap is using=20 the OpenLDAP 2.1 libs. I did not have the possibility to track=20 down this issue.) See example: http://sites.inka.de:8002/web2ldap?ldap://ldap.rediris.es/dc%3Des??one? (Please use [Disconnect] after use to quickly erase the LDAP=20 connection. This demo runs on a restricted shell-account allowing=20 only 24 file handles). Example code: ------------------------------------------------------------------- import ldap l=3Dldap.initialize('ldap://ldap.rediris.es') l.set_option(ldap.OPT_PROTOCOL_VERSION,ldap.VERSION3) l.set_option(ldap.OPT_REFERRALS,0) result =3D l.search_s('dc=3Des',ldap.SCOPE_ONELEVEL,'(objectClass=3D*)') for i in result: print i ------------------------------------------------------------------- Ciao, Michael. |
|
From: Robert S. <ml-...@ep...> - 2002-07-25 21:01:14
|
On Thu, 25 Jul 2002 10:45:12 +0000 (UTC),
Michael Ströder <mi...@st...> wrote:
> import ldap
>
> l=ldap.initialize('ldap://ldap.rediris.es')
> l.set_option(ldap.OPT_PROTOCOL_VERSION,ldap.VERSION3)
> l.set_option(ldap.OPT_REFERRALS,0)
> result = l.search_s('dc=es',ldap.SCOPE_ONELEVEL,'(objectClass=*)')
> for i in result:
> print i
Thanks for the example code. That actually works!
I think I have to check all these options and their meaning again. ;-)
Greetings
--
Robert Sander
Manager
Information Systems www.epigenomics.com Kastanienallee 24
+493024345330 10435 Berlin
|
|
From: <mi...@st...> - 2002-07-25 21:23:57
|
Michael Str=F6der wrote: >=20 > If you switch off internal referral handling you will receive search=20 > continuations along with normal search results as tuples with None as=20 > first item and a string containing the LDAP URL as second item. I forgot something: If the search root is itself matched by a=20 referral a ldap.REFERRAL exception is raised. You have to extract the referral's LDAP URL and matched field from=20 the exception instance. Feel free to check out web2ldap's sources=20 pylib/w2lapp/handler.py and pylib/w2lapp/referral.py. Your mileage=20 may vary. Note that there are many issues to deal with either in your=20 concept or your application when extensively using referrals. Ciao, Michael. |
|
From: Robert S. <gur...@ep...> - 2002-07-26 05:26:38
|
On Thu, Jul 25, 2002 at 11:21:17PM +0200, Michael Ströder wrote: > I forgot something: If the search root is itself matched by a > referral a ldap.REFERRAL exception is raised. I already got that exception. > Note that there are many issues to deal with either in your > concept or your application when extensively using referrals. We have a "wrapper" search function that will deal with this. Greetings -- Robert Sander Manager Information Systems www.epigenomics.com Kastanienallee 24 +493024345330 10435 Berlin |
|
From: <mi...@st...> - 2002-07-26 10:42:46
|
Robert Sander wrote: > >>Note that there are many issues to deal with either in your >>concept or your application when extensively using referrals. > > We have a "wrapper" search function that will deal with this. This might be a nice inspiration for python-ldap. Ciao, Michael. |
|
From: Robert S. <ml-...@ep...> - 2002-07-28 17:48:55
|
On Fri, 26 Jul 2002 10:43:28 +0000 (UTC),
Michael Ströder <mi...@st...> wrote:
>> We have a "wrapper" search function that will deal with this.
>
> This might be a nice inspiration for python-ldap.
Good, I haven't tested it very well, but it seems to work.
Here it is:
import ldap, ldapurl
def ldapsearch(self,
server,
base,
scope = ldap.SCOPE_SUBTREE,
filter,
attrs = None,
attrsonly = 0,
binddn = None,
bindpw = None,
debug = None):
if debug:
print "%s [%s]: %s; %s" % (server, base, filter, attrs)
l = ldap.open(server)
l.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)
l.set_option(ldap.OPT_REFERRALS, 0)
l.simple_bind_s(binddn, bindpw)
hash = {}
if self.debug:
print " searching in %s for %s" % ( base, filter )
try:
for entry, values in l.search_s(base, scope, filter, attrs, attrsonly):
if entry:
hash[entry] = values
if debug:
print " found %s" % entry
else:
for value in values:
if debug:
print " got reference to %s" % value
url = ldapurl.LDAPUrl(value)
hash.update(ldapsearch(server=url.hostport, base=url.dn, scope=scope, filter=filter, attrs=attrs, attrsonly=attrsonly, binddn=binddn, bindpw=bindpw, debug=debug))
except ldap.REFERRAL, er:
if er.has_key('info'):
url = ldapurl.LDAPUrl(er['info'])
hash.update(ldapsearch(server=url.hostport, base=url.dn, scope=scope, filter=filter, attrs=attrs, attrsonly=attrsonly, binddn=binddn, bindpw=bindpw, debug=debug))
l.unbind()
return hash
It fills a hash indexed by the dn with the value of the dn.
Currently it needs the same binddn on every server accessed. But you can
easily integrate a method that returns a new binddn and bindpw depending
on the server and/or the search base.
Greetings
--
Robert Sander
Manager
Information Systems www.epigenomics.com Kastanienallee 24
+493024345330 10435 Berlin
|