Создайте "последовательность последовательности" объекта ldap.controls.RequestControl

Я использую python-ldap для поиска ActiveDirectory, как если бы это был обычный сервер LDAP. Работает, SSL, аутентификация и все.

Теперь я хочу использовать элемент управления запросом сортировки на стороне сервера, определенный в RFC 2891, который имеет OID 1.2.840.113556.1.4.473,

Python-ldap не поддерживает этот элемент управления "из коробки", поэтому я должен создать его сам. Я сделал это:

server_side_sort = ldap.controls.RequestControl('1.2.840.113556.1.4.473', True) 

Но я не знаю, как вычислить encodedControlValue параметр, который является BER-закодированным значением управления ASN.1.

я вижу это pyasn1 имеет много частей, чтобы вычислить это, как univ.SequenceOf, univ.Sequence а также univ.Boolean, Глядя на модуль RFC2251 из pyasn1, я придумал это:

class LDAPString(univ.OctetString): pass

class AttributeDescription(LDAPString): pass

class MatchingRuleId(LDAPString): pass

class ServerSideSortOnName(univ.Sequence):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('attributeDesc', AttributeDescription('name')), 
        namedtype.NamedType('reverseOrder', univ.Boolean(False)) )

class ServerSideSortControl(univ.SequenceOf):
     componentType = ServerSideSortOnName()

sss = ServerSideSortControl()

serversidesort = ldap.controls.RequestControl('1.2.840.113556.1.4.473',True,sss)

Имя не может быть проиндексировано, я знаю. Я думал, что это может помочь отладке соответствовать значению base64, показанному в этом фрагменте MSDN.

Но когда я добавляю этот элемент управления (который может быть даже недействительным) в ldap.search_ext, я получаю сообщение об ошибке TypeError: ('expected a string', ServerSideSortControl())

Как я могу создать значение управления сортировкой на стороне сервера для атрибута name этот питон-LDAP ldap.search_ext примет, используя pyasn1 или подобное?

1 ответ

Решение

Вы должны гнездиться univ.Sequence в univ.SequenceOf и реализовать encodeControlValue возвращает кодированный BER элемент управления, ожидаемый сервером.

class SSSRequest(univ.SequenceOf):
    componentType = univ.Sequence()

class SSSRequestSequence(univ.Sequence):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('attributeType', univ.OctetString()),
    )

class SSS_CONTROL_REQUEST(LDAPControl):
    def __init__(self,controlType,criticality,controlValue=None,encodedControlValue=None):
        LDAPControl.__init__(self,controlType,criticality,controlValue,encodedControlValue)

    def encodeControlValue(self):
        sss = SSSRequest()

        for k in self.controlValue:
            Skey = SSSRequestSequence()
            Skey.setComponentByName('attributeType', k)
            sss.setComponentByPosition(0, Skey)
        return encoder.encode(sss)

    def decodeControlValue(self,encodedValue):
        sssr = decoder.decode(encodedValue)[0]
        rsp = SSSResponse()
        for n, v in enumerate(sssr):
            try:
                rsp.setComponentByPosition(n, int(v))
            except Exception, e:
                print str(e)
        if rsp.success:
            return True
        return rsp.error

if __name__ == '__main__':
    SSSREQUEST_OID = '1.2.840.113556.1.4.473'
    sss = SSS_CONTROL_REQUEST(SSSREQUEST_OID, False, ['cn'])
    srv = ldap.open('localhost')
    srv.simple_bind_s()
    id = srv.search_ext('ou=people,dc=example,dc=com', ldap.SCOPE_SUBTREE, filterstr='(objectClass=user)', serverctrls=[sss])
    print srv.result3(id)

Реализация сортировки в обратном порядке оставлена ​​в качестве упражнения;)

Код был успешно протестирован с экземпляром AD-LDS, работающим на Windows Server 2008 R2, 64 бита (но вы должны сделать привязку неанонимной).

Другие вопросы по тегам