Поиск Python-ldap: превышен лимит размера

Я использую библиотеку python-ldap для подключения к нашему серверу LDAP и выполнения запросов. Проблема, с которой я столкнулся, заключается в том, что, несмотря на ограничение размера поиска, я продолжаю получать ошибки SIZELIMIT_EXCEEDED по любому запросу, который возвращает слишком много результатов. Я знаю, что сам запрос работает, потому что я получу результат, если запрос вернет небольшое подмножество пользователей. Даже если я установлю ограничение размера на что-то абсурдное, например 1, я все равно получу SIZELIMIT_EXCEEDED для этих больших запросов. Я вставил общую версию моего запроса ниже. Любые идеи относительно того, что я делаю неправильно здесь?

result = self.ldap.search_ext_s(self.base, self.scope, '(personFirstMiddle=<value>*)', sizelimit=5)

person devights    schedule 24.07.2012    source источник


Ответы (2)


Когда клиент LDAP запрашивает ограничение размера, это называется «запрошенным клиентом» ограничением размера. Ограничение размера, запрошенное клиентом, не может переопределить ограничение размера, установленное сервером. Сервер может установить ограничение размера для сервера в целом, для определенного идентификатора авторизации или по другим причинам - в любом случае клиент не может переопределить ограничение размера сервера. Запрос на поиск может быть выдан в нескольких частях с использованием элемента управления simple paged results или элемента управления virtual list view.

person Terry Gardner    schedule 25.07.2012
comment
Этот ответ совершенно неверен. Также совет с простыми страницами результатов для обхода ограничения на стороне сервера работает только с MS AD. - person Michael Ströder; 21.09.2018

Вот реализация Python3, которую я придумал после тщательного редактирования того, что я нашел здесь и в официальной документации. На момент написания этой статьи он работал с пакетом pip3 python-ldap версии 3.2.0. .

def get_list_of_ldap_users():
    hostname = "google.com"
    username = "username_here"
    password = "password_here"
    base = "dc=google,dc=com"

    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)
    connect=ldap_server
    search_flt = "(personFirstMiddle=<value>*)" # get all users with a specific middle name
    page_size = 500 # how many users to search for in each page, this depends on the server maximum setting (default is 1000)
    searchreq_attrlist=["cn", "sn", "name", "userPrincipalName"] # 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 :)

person Josh Correia    schedule 15.05.2020