LDAP: ldap.SIZELIMIT_EXCEEDED

13 投票
6 回答
24244 浏览
提问于 2025-04-16 02:07

我在运行这段代码时遇到了一个 ldap.SIZELIMIT_EXCEEDED 的错误:

import ldap

url = 'ldap://<domain>:389'
binddn = 'cn=<username> readonly,cn=users,dc=tnc,dc=org'
password = '<password>'

conn = ldap.initialize(url)
conn.simple_bind_s(binddn,password)

base_dn = "ou=People,dc=tnc,dc=org"
filter = '(objectClass=*)'
attrs = ['sn']

conn.search_s( base_dn, ldap.SCOPE_SUBTREE, filter, attrs )

这里的 username 是我的真实用户名,password 是我的真实密码,domain 是我的真实域名。

我不太明白为什么会这样。有人能帮我解释一下吗?

6 个回答

2

如果你遇到这个错误,可以参考这里的解决办法:

如何在Python LDAP中获取超过服务器大小限制的更多搜索结果?

6

你遇到这个异常,很可能是因为你正在和的服务器返回的结果数量超过了一次请求能处理的范围。为了绕过这个问题,你需要使用分页结果,这可以通过使用SimplePagedResultsControl来实现。

下面是我自己写的一个Python3实现,经过了大量修改,参考了这里官方文档。在写这段内容时,它与pip3包python-ldap版本3.2.0兼容。

def get_list_of_ldap_users():
    hostname = "<domain>:389"
    username = "username_here"
    password = "password_here"
    base = "ou=People,dc=tnc,dc=org"

    print(f"Connecting to the LDAP server at '{hostname}'...")
    connect = ldap.initialize(f"ldap://{hostname}")
    connect.set_option(ldap.OPT_REFERRALS, 0)
    connect.simple_bind_s(username, password)
    search_flt = "(objectClass=*)"
    page_size = 500 # how many users to search for in each page, this depends on the server maximum setting (default highest value is 1000)
    searchreq_attrlist=["sn"] # change these to the attributes you care about
    req_ctrl = SimplePagedResultsControl(criticality=True, size=page_size, cookie='')
    msgid = connect.search_ext(base=base, scope=ldap.SCOPE_SUBTREE, filterstr=search_flt, attrlist=searchreq_attrlist, serverctrls=[req_ctrl])

    total_results = []
    pages = 0
    while True: # loop over all of the pages using the same cookie, otherwise the search will fail
        pages += 1
        rtype, rdata, rmsgid, serverctrls = connect.result3(msgid)
        for user in rdata:
            total_results.append(user)

        pctrls = [c for c in serverctrls if c.controlType == SimplePagedResultsControl.controlType]
        if pctrls:
            if pctrls[0].cookie: # Copy cookie from response control to request control
                req_ctrl.cookie = pctrls[0].cookie
                msgid = connect.search_ext(base=base, scope=ldap.SCOPE_SUBTREE, filterstr=search_flt, attrlist=searchreq_attrlist, serverctrls=[req_ctrl])
            else:
                break
        else:
            break
    return total_results

这个代码会返回所有用户的列表,但你可以根据需要进行修改,以返回你想要的内容,而不会遇到SIZELIMIT_EXCEEDED的问题 :)

6

手册链接: http://www.python-ldap.org/doc/html/ldap.html

异常 ldap.SIZELIMIT_EXCEEDED
这个错误表示你请求的数据超出了LDAP服务器的大小限制。这可能是因为LDAP服务器上设置了一个sizelimit的配置。

我觉得你可以尝试限制一下从服务器收到的sizelimit。你可以通过设置属性LDAPObject.sizelimit(这个方法已经不推荐使用了)或者在使用search_ext()时使用sizelimit参数来实现。

另外,你还要确保你的绑定操作实际上是成功的……

撰写回答