创建一个";“顺序的顺序”;ldap.controls.RequestControl对象

创建一个";“顺序的顺序”;ldap.controls.RequestControl对象,ldap,asn.1,python-ldap,Ldap,Asn.1,Python Ldap,我使用python ldap搜索ActiveDirectory,就像它是任何常规ldap服务器一样。它可以工作,包括SSL、身份验证和其他一切 现在我想使用,它的OID1.2.840.113556.1.4.473 Python ldap不支持这种开箱即用的控件,所以我必须自己创建它。我这样做: server_side_sort = ldap.controls.RequestControl('1.2.840.113556.1.4.473', True) 但是我不知道如何计算encodedCon

我使用python ldap搜索ActiveDirectory,就像它是任何常规ldap服务器一样。它可以工作,包括SSL、身份验证和其他一切

现在我想使用,它的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
参数,它是

我看到
pyasn1
有很多部分要组成,比如
univ.SequenceOf
univ.Sequence
univ.Boolean
。看着照片,我想到了这个:

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)
我知道名字可能没有索引。我认为这有助于调试匹配

但是,当我将此控件(甚至可能无效)添加到ldap.search_ext时,我得到了错误
TypeError:('expected a string',ServerSideSortControl())


如何在python ldap
ldap.search\u ext
将接受的属性
name
上创建服务器端排序控制值,使用pyasn1或类似的?

您必须在
univ.SequenceOf
中嵌套
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)
实现逆序排序留作练习;)


该代码已通过在Windows Server 2008 R2上运行的64位AD-LDS实例成功测试(但您必须使绑定非匿名)。

谢谢!您的原始代码没有按原样运行。我用一个在我的机器上运行的更新了它。