[python-ldap] Adding members to a group in AD

Michael Ströder michael at stroeder.com
Mon Aug 29 13:32:39 CEST 2011

Russell Jackson wrote:
> modifyModList() is a bit ham fisted in that it just does a replace rather than
> figure out what to add and delete. 

More precise: modifyModList() will result in MOD_DEL all values, MOD_ADD
complete new value list. The reason for this is that not all attributes have
an EQUALITY matching rule assigned to it (e.g. binary attributes) which is
required for doing something smarter. This turned out to be successful with
most LDAP servers. But some LDAP server seem to do schema-checking not on the
overall result of the modify operation. It seems that MOD_DEL all values leads
to a schema violation one these servers.

My web2ldap has a smarter variant of this function which looks in the
subschema for determining whether an EQUALITY matching rule is usable.

Anyway one would not want to use that for large group entries.

> dn, entry = dir.search_s('dc=domain', ldap.SCOPE_SUBTREE, '''
> (&
>   (objectClass=group)
>   (cn=some_group)
> )
> '''.strip())[0]
> member_dn_list = [
>   'cn=foo,ou=people,dc=domain',
>   'cn=bar,ou=people,dc=domain',
>   'cn=baz,ou=people,dc=domain',
> ]
> modlist = [
>   (ldap.MOD_ADD, 'member', [
>     dn
>     for dn in member_dn_list
>     if dn not in entry.get('member', [])
>   ])
> ]
> ldif.LDIFWriter(sys.stderr).unparse(dn, modlist)
> dir.modify_s(dn, modlist)

Hmm, in principle this is ok but one should make it a bit faster by
pre-initializing a set. Also one might to make this case-insensitive.

I'd usually do:

member_list = set([av.lower() for av in entry.get('member', [])])

and then:

if not dn.lower() in member_list:

If one already knows which DN to add it's more easy anyway.

Note that DNs are not case-insensitive in general. E.g. OpenLDAP looks applys
the exact matching rules for the attributes used in a DN.

Ciao, Michael.

More information about the python-ldap mailing list