我使用python-ldap搜索ActiveDirectory,就像它是任何常规LDAP服务器一样。它工作,SSL,身份验证和一切。
现在我想使用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
有许多部分需要对其进行评估,例如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())
如何使用pyasn1或类似方法在python-ldap name
接受的属性ldap.search_ext
上创建服务器端排序控件值?
答案 0 :(得分: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)
实施逆序排序仍然是一个练习;)
使用在Windows Server 2008 R2上运行的AD-LDS实例(64位)成功测试了代码(但您必须使绑定非匿名)。