Создайте "последовательность последовательности" объекта 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 бита (но вы должны сделать привязку неанонимной).