Найдите максимальный UID с помощью Python-LDAP

Я пытаюсь найти/искать максимальное значение UID в записи LDAP, используя модуль python. Мой код выглядит примерно так на время

def search_max_uid():
    filter_uid = 'uid=*'
    attributes = ['uidNumber']
    resulting = l.search_ext(base_dn,ldap.SCOPE_SUBTREE,filter_uid,attributes)
    print resulting

Как только я получу максимальный UID со всего сервера, я могу +1 и добавить нового пользователя в группу. Я видел несколько сообщений типа http://www.openldap.org/lists/openldap-software/200110/msg00539.html и http://www.perlmonks.org/?node_id=457108, которые очень похожи на мой вопрос

Может ли кто-нибудь помочь мне найти максимальный UID, чтобы я мог решить эту проблему.


person Nishant Singh    schedule 02.04.2018    source источник


Ответы (2)


Пытаясь решить что-то подобное, я думаю, что это работает при получении следующего доступного uidNumber:

import ldap

l = ldap.initialize("ldap://localhost")
l.simple_bind_s("cn=blah,dc=blah,dc=blah", supersecretpassword)
res = l.search_s("dc=blah,dc=blah", ldap.SCOPE_SUBTREE, 'objectclass=posixaccount', ['uidNumber'])
uidNum = 0

for a in res:
    uidNumtemp = a[1].get('uidNumber')[0]
    if uidNumtemp > uidNum:
       uidNum = uidNumtemp
print "Highest:", uidNum
nextNum = int(uidNum) + 1
print "next uidNumber:", nextNum
person Che Stevens    schedule 20.04.2018

Если вы используете сервер LDAP, поддерживающий сортировку на стороне сервера (см. RFC 2891), например OpenLDAP с помощью slapo-sssvlv вы можете искать наибольшее число, поиск только одного результата поиска с обратным порядком сортировки.

Фрагмент кода Python на основе python-ldap (отрывок из одного из Æ-DIR CLI-инструменты):

import ldap
from ldap.controls.sss import SSSRequestControl

def highest_id(ldap_conn, searchbase, id_attr):
    """
    search the highest value of `id_attr' by using server-side (reverse) sorting
    """
    # reverse sorting request control
    sss_control = SSSRequestControl(criticality=True, ordering_rules=['-'+id_attr])
    # send search request
    msg_id = ldap_conn.search(
        searchbase,
        ldap.SCOPE_SUBTREE,
        '({0}=*)'.format(id_attr),
        attrlist=[id_attr],
        sizelimit=1,
        serverctrls=[sss_control],
    )
    # collect result
    ldap_result = []
    try:
        for _, res_data, _, res_controls in ldap_conn.results(
                msg_id,
                add_ctrls=0
            ):
            ldap_result.extend(res_data)
    except ldap.SIZELIMIT_EXCEEDED:
        pass

    if not ldap_result:
        logging.error('No entry with attribute %r found!', id_attr)
        raise ValueError('No LDAP result!')

    highest_id_number = int(ldap_result[0][1][id_attr][0])
    logging.debug('Highest %r value found: %d', id_attr, highest_id_number)
    return highest_id_number

Обратите внимание, что это не всегда то, что вам нужно при назначении новых идентификаторов, поскольку пробелы в пространстве идентификационных номеров не (повторно) используются.

Также обязательно используйте уникальный плагин ограничения на стороне сервера, например. Наложение OpenLDAP slapo-unique. Это позволяет избежать дублирования в случае, если параллельные клиенты добавляют новые записи.

person Michael Ströder    schedule 31.07.2018
comment
Обратите внимание, что этот фрагмент не работает. база поиска нигде не определена - person alex067; 20.08.2020
comment
Спасибо за указание на это. Это было вызвано копированием кода, который является методом и, таким образом, использует атрибут экземпляра. Отредактировал мой ответ. - person Michael Ströder; 22.08.2020