Python LDAP:LDAP.SIZELIMIT_已超出

Python LDAP:LDAP.SIZELIMIT_已超出,python,ldap,Python,Ldap,运行此代码时,我收到一个ldap.SIZELIMIT\u超出的错误: 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 =

运行此代码时,我收到一个
ldap.SIZELIMIT\u超出的
错误:

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 )
导入ldap
url='ldap://:389'
binddn='cn=readonly,cn=users,dc=tnc,dc=org'
密码=“”
conn=ldap.initialize(url)
conn.simple\u bind\s(binddn,密码)
base_dn=“ou=People,dc=tnc,dc=org”
过滤器='(对象类=*)'
属性=['sn']
conn.search(基本dn、ldap.SCOPE子树、筛选器、属性)
其中,
username
是我的实际用户名,
password
是我的实际密码,
domain
是实际域

我不明白这是为什么。有人能给我们点启示吗?

手册:

异常
ldap
SIZELIMIT\u超过
超出了LDAP大小限制。这
可能是由于
sizelimit
LDAP服务器上的配置

我认为您最好的选择是限制从服务器收到的消息的
sizelimit
。您可以通过设置属性
LDAPObject.sizelimit
(已弃用)或在使用
search\u ext()时使用sizelimit参数来实现这一点


您还应该确保绑定实际成功…

Active Directory默认情况下最多返回1000个结果。有点恼人的是,它似乎没有返回1000,并返回相关的错误代码,而是发送了没有数据的错误代码

eDirectory一开始没有默认值,并且完全可用于任何您喜欢的内容


其他目录的处理方式不同。(如果您知道,请编辑和加载项)。

有关出现此错误时的操作,请参见此处:

您提供的筛选器(
objectClass=*
)是状态筛选器。在这种情况下,它将搜索结果限制为对您提供的基本对象所在目录下的对象的搜索请求-这是基本对象下的每个对象,因为每个对象至少有一个
objectClass
。通过使用更严格的过滤器、更严格的范围、更低的基本对象或所有三种方法来限制搜索。有关搜索请求主题的更多信息,请参阅和

目录服务器管理员可以自由地对可以返回到LDAP客户端的条目施加服务器范围的限制,这些限制称为服务器施加的大小限制。有一个遵循同样规则的时限


LDAP客户端应始终为搜索请求提供大小限制和时间限制,但这些限制(称为客户端请求的限制)不能覆盖服务器施加的限制。

必须使用分页搜索来实现这一点。 页面大小取决于ldap服务器,1000适用于Active Directory


请看一个示例

您很可能会遇到该异常,因为您正在与之通信的服务器的结果比单个请求返回的结果多。为了解决这个问题,您需要使用分页结果,这可以通过使用来完成

这里有一个Python3实现,我在大量编辑了我在。在编写本文时,它与pip3包版本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
def get_list_of_ldap_用户():
hostname=“:389”
username=“username\u此处”
password=“password\u此处”
base=“ou=People,dc=tnc,dc=org”
打印(f“连接到位于{hostname}的LDAP服务器…”)
connect=ldap.initialize(f“ldap://{hostname}”)
connect.set_选项(ldap.OPT_引用,0)
连接。简单绑定(用户名、密码)
search_flt=“(objectClass=*)”
page_size=500#在每个页面中搜索多少用户,这取决于服务器的最大设置(默认最大值为1000)
searchreq_attrlist=[“sn”]#将这些更改为您关心的属性
req\u ctrl=SimplePagedResultsControl(关键性=True,大小=page\u大小,cookie='')
msgid=connect.search\u ext(base=base,scope=ldap.scope\u子树,filterstr=search\u flt,attrlist=searchreq\u attrlist,serverctrls=[req\u ctrl])
总结果=[]
页数=0
如果为True:#使用同一cookie在所有页面上循环,否则搜索将失败
页数+=1
rtype、rdata、rmsgid、serverctrls=connect.result3(msgid)
对于rdata中的用户:
结果总数。追加(用户)
pctrls=[c代表服务器CTRL中的c,如果c.controlType==SimplePagedResultsControl.controlType]
如果pctrls:
如果pctrls[0]。cookie:#将cookie从响应控件复制到请求控件
请求\u ctrl.cookie=pctrls[0]。cookie
msgid=connect.search\u ext(base=base,scope=ldap.scope\u子树,filterstr=search\u flt,attrlist=searchreq\u attrlist,serverctrls=[req\u ctrl])
其他:
打破
其他:
打破
返回总结果

这将返回所有用户的列表,但您可以根据需要对其进行编辑,以返回您想要的内容,而无需点击
SIZELIMIT.
issue:)

谢谢。我想这应该是我的第一个来源。应该注意的是,虽然您可以使用
search\u ext(size=desired\u num)
来避免
ldap.SIZELIMIT\u超出了
异常,但这不会让您查看所有用户。sizelimit不会覆盖服务器的设置,因此,如果服务器将sizelimit设置为100个用户,则不能将大小设置为500,然后期望所有用户都返回。我认为这是真的。所以,我现在要做的是按姓氏的第一个字母返回查询。这比一次显示数千名员工要好。请注意,按姓名的第一个字母搜索不起作用。因为最终您的数据集将变得足够大,可以返回1000多个,以此类推。。。