python中的LDAP查询

python中的LDAP查询,python,ldap,ldap-query,Python,Ldap,Ldap Query,我想在ldap中执行以下查询 ldapsearch -h hostname -b dc=ernet,dc=in -x "(&(uid=w2lame)(objectClass=posixAccount))" gidnumber ldapsearch -h hostname -b dc=ernet,dc=in -x "(&(gidNumber=1234)(objectClass=posixGroup))" cn 并使用由此获得的变量。如何才能做到这一点?您可以使用命令模块和geto

我想在ldap中执行以下查询

ldapsearch -h hostname -b dc=ernet,dc=in -x "(&(uid=w2lame)(objectClass=posixAccount))" gidnumber
ldapsearch -h hostname -b dc=ernet,dc=in -x "(&(gidNumber=1234)(objectClass=posixGroup))" cn

并使用由此获得的变量。如何才能做到这一点?

您可以使用命令模块和getoutput解析ldap查询的结果:

from commands import getoutput
result = getoutput('ldapsearch -h hostname -b dc=ernet,dc=in -x "(&(uid=w2lame)(objectClass=posixAccount))"')
print result
您必须在系统中安装ldapsearch二进制文件


关于。-

您可能想使用该模块。代码看起来像:

import ldap
l = ldap.initialize('ldap://ldapserver')
username = "uid=%s,ou=People,dc=mydotcom,dc=com" % username
password = "my password"
try:
    l.protocol_version = ldap.VERSION3
    l.simple_bind_s(username, password)
    valid = True
except Exception, error:
    print error

下面是一个python ldap的示例生成器

ldap\u服务器是从ldap.initialize()获取的对象。在调用此函数之前,您可能也需要进行绑定,这取决于您使用的LDAP服务器以及您试图查询的内容。
base\u dn
filter\u
与命令行版本中的类似。
限制
是返回的最大记录数

def _ldap_list(ldap_server, base_dn, filter_, limit=0):
    """ Generator: get a list of search results from LDAP asynchronously. """

    ldap_attributes = ["*"] # List of attributes that you want to fetch.
    result_id = ldap_server.search(base_dn, ldap.SCOPE_SUBTREE, filter_, ldap_attributes)
    records = 0

    while 1:
        records += 1

        if limit != 0 and records > limit:
            break

        try:
            result_type, result_data = ldap_server.result(result_id, 0)
        except ldap.NO_SUCH_OBJECT:
            raise DirectoryError("Distinguished name (%s) does not exist." % base_dn)

        if result_type == ldap.RES_SEARCH_ENTRY:
            dn = result_data[0][0]
            data = result_data[0][1]
            yield dn, data
        else:
            break

请记住,在LDAP查询中插入用户提供的值是危险的这是一种注入形式,允许恶意用户更改查询的含义。请参阅:

虽然公认的答案确实显示了绑定到LDAP服务器的正确方法,但我确实觉得它没有完整地回答这个问题。下面是我最终实现的内容,用于抓取用户的邮件和部门。这在某种程度上混合了原始问题所需的属性

l = ldap.initialize('ldap://ldap.myserver.com:389')
binddn = "cn=myUserName,ou=GenericID,dc=my,dc=company,dc=com"
pw = "myPassword"
basedn = "ou=UserUnits,dc=my,dc=company,dc=com"
searchFilter = "(&(gidNumber=123456)(objectClass=posixAccount))"
searchAttribute = ["mail","department"]
#this will scope the entire subtree under UserUnits
searchScope = ldap.SCOPE_SUBTREE
#Bind to the server
try:
    l.protocol_version = ldap.VERSION3
    l.simple_bind_s(binddn, pw) 
except ldap.INVALID_CREDENTIALS:
  print "Your username or password is incorrect."
  sys.exit(0)
except ldap.LDAPError, e:
  if type(e.message) == dict and e.message.has_key('desc'):
      print e.message['desc']
  else: 
      print e
  sys.exit(0)
try:    
    ldap_result_id = l.search(basedn, searchScope, searchFilter, searchAttribute)
    result_set = []
    while 1:
        result_type, result_data = l.result(ldap_result_id, 0)
        if (result_data == []):
            break
        else:
            ## if you are expecting multiple results you can append them
            ## otherwise you can just wait until the initial result and break out
            if result_type == ldap.RES_SEARCH_ENTRY:
                result_set.append(result_data)
    print result_set
except ldap.LDAPError, e:
    print e
l.unbind_s()

在有Python库的情况下使用命令从来都不是一个好主意。有些公司使用自定义IT命令与基础设施进行内部交互,可能需要使用此类命令以避免IT执行部门的访问。“永不说不”。一些Python库,如前面提到的Python ldap,有如此复杂的外部构建需求,并且没有正式的二进制文件,对于小任务来说,真的不值得费心去强迫它们工作。这个解决方案非常适合一些快速测试。我疯了吗,还是这不能回答问题?他在问如何运行查询,而你在向他展示如何绑定。@mehasse:这个示例旨在展示ldap模块的常见用法,我认为它确实如此。如果您试图执行查询,可以在ldap对象上使用.search方法。更好的用户
search\s()
避免
而1
完成@Caumons注释;要避免使用while 1,请执行以下操作:
res=l.search(basedn、searchScope、searchFilter、searchAttribute)
print res
l.unbind_s()