2013-06-27 1 views
1

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

Теперь я хочу использовать server side sort request control defined in 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, который the BER-encoded ASN.1 control value.

Я вижу, что pyasn1 имеет много частей к comptue его, как univ.SequenceOf, univ.Sequence и univ.Boolean. Глядя на RFC2251 module of 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 value shown on this MSDN snippet.

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

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

ответ

2

Вы должны вложить 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) 

Реализация обратный порядок сортировки осталось как exercice;)

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

+0

Спасибо! Исходный код не был запущен как есть. Я обновил его с помощью той, которая работает на моей машине. – ixe013

 Смежные вопросы

  • Нет связанных вопросов^_^