Search-Filter for LDAP (MS Active Directory)

Ames Andreas (MPA/DF) Andreas.Ames at tenovis.com
Thu Oct 14 11:03:27 EDT 2004


Hello,

Dirk Hagemann wrote:

> I'd like to know how to set up a query for all computer-accounts in
> a special part of Active Directory by using LDAP.
>
> Example:
> all computers with a name like "ABC*" at "..., ou=Production,
> DC=business,DC=company,DC=com"
>>From these computers I want to get their OS, Service Pack and some
> other information.

I use python-ldap (http://python-ldap.sf.net/) to access Active
Directory.  Example:

# ----------------- code start -----------------
import ldap, ldapurl

proto = 'ldap'
server = 'youradserver.yourdomain.com'
port = 389

url = ldapurl.LDAPUrl(urlscheme=proto,
                      hostport="%s:%s" % (server,
                      str(port))).initializeUrl()
ldap_obj = ldap.initialize(url)

# !!!password will be on wire in plaintext!!!
ldap_obj = ldap_obj.simple_bind_s('<domainuser>',
                                  '<password>')

# search only within given subtree
base = 'ou=Production, DC=business, dc=yourdomain, dc=com'

# search scope see rfcs for explanation; in your case it's probably:
scope = ldap.SCOPE_SUBTREE

# this is the beef, i.e. the rfc2254 filter the following matches all
# entries in the directory, which might be many.  OTOH, you often have
# server site limits on how much search hits may be returned for a
# single query; I dunno how this is changed within the query (probably
# some filter extension magic I haven't used yet)
query = '(objectclass=*)'

# now your job is to find out the right query string; I don't know if
# for example computer accounts have a special objectclass, so I'll
# just assume it is called 'cAccount'.  Further I don't know which
# attribute type denotes the name of the computer account you
# mentioned; I'll just assume its type is called 'displayname'.  Under
# these assumptions your example above would translate to the
# following query (which won't work because my assumptions are
# certainly wrong):
# query = '(&(objectclass=cAccount)(displayname=abc*))'

# limit the attribute types which you want to see in the result
# the following will give you the values of all attribute types of
# all matching directory entries
res_attrs = ['*']

res = ldap_obj.search_ext_s(base, scope, query, res_attrs)
print res
# ----------------- code end -----------------


I haven't tested this special code but I'm using similar code on a
daily basis.

If you are like many people and don't like plaintext passwords on the
wire you have at least two alternatives:  TLS and SASL.  TLS in Active
Directory means you'll want to use 'ldaps' as the urlscheme (start_tls
doesn't work yet, AFAIK).

I had no luck with sasl (only GSSAPI available in my case).  Although
I can get a TGT with MIT's kinit from my Active Directory server (this
is debian, I dunno how to get the TGT on a Micros~1 platform, but the
MIT's Windows port of their client tools seems to have some support),
there seems to be a bug related to packet sizes (either in AD or in
openldap's libldap).  Maybe
http://www.openldap.org/lists/openldap-devel/200211/msg00035.html
could get you going.


HTH,

andreas




More information about the Python-list mailing list