[python-ldap] Deref request control appears to not recieve results,
William Brown
william at blackhats.net.au
Wed Aug 26 03:35:26 CEST 2015
Hi,
I am trying to write a dereference control [0] to use for the 389ds project,
with the intent that once it is working, to include it in python-ldap.
I am adding the control to the search with:
try:
drc = DereferenceControl(True, deref=deref.encode('UTF-8'))
sctrl = [drc]
self.set_option(ldap.OPT_SERVER_CONTROLS, sctrl)
res = self.search(base, scope, *args, **kwargs)
resp_type, resp_data, resp_msgid, decoded_resp_ctrls = self.result3(res,
resp_ctrl_classes={CONTROL_DEREF: DereferenceControl})
finally:
self.set_option(ldap.OPT_SERVER_CONTROLS, [])
return resp_data, decoded_resp_ctrls
The request is formatted correctly through the control [1], and I can see the
search on the 389ds server as:
[26/Aug/2015:10:49:04 +091800] deref-plugin - --> deref_pre_search
[26/Aug/2015:10:49:04 +091800] deref-plugin - <-- deref_pre_op
[26/Aug/2015:10:49:05 +091800] - Calling plugin 'deref' #2 type 410
[26/Aug/2015:10:49:05 +091800] deref-plugin - deref slapi_value_get_string
uid=test,dc=example,dc=com
[26/Aug/2015:10:49:05 +091800] - Calling plugin 'deref' #2 type 403
[26/Aug/2015:10:49:05 +091800] deref-plugin - --> deref_pre_search
[26/Aug/2015:10:49:05 +091800] deref-plugin - <-- deref_pre_op
[26/Aug/2015:10:49:05 +091800] - Calling plugin 'deref' #2 type 410
[26/Aug/2015:10:49:05 +091800] deref-plugin - Added control -1073736768
[26/Aug/2015:10:49:05 +091800] deref-plugin - Sending deref results to client
So I can see that the control is processed, the search occurs, and the correct
result of uid=test is found and dereferenced, and the control is added to the
server response.
However, with trace_level=3, I don't see this result in python ldap:
*** <lib389.DirSrv instance at 0x7f9625f6d2d8>
ldap://localhost.localdomain:54321/ - DirSrv.set_option
((18,
[('1.3.6.1.4.1.4203.666.5.16',
True,
'0\x1b0\x19\x04\x0cuniqueMember0\t\x04\x03uid\x04\x02dn')]),
{})
=> result:
None
...
*** <lib389.DirSrv instance at 0x7f9625f6d2d8>
ldap://localhost.localdomain:54321/ - DirSrv.search_ext
(('dc=example,dc=com', 2, '(cn=testgroup)', None, 0, None, None, -1, 0), {})
=> result:
8
...
*** <lib389.DirSrv instance at 0x7f9625f6d2d8>
ldap://localhost.localdomain:54321/ - DirSrv.result4
((8, 1, -1, 0, 0, 0), {})
=> result:
(101,
[('cn=testgroup,dc=example,dc=com',
{'cn': ['testgroup'],
'objectClass': ['top', 'extensibleobject'],
'uniqueMember': ['uid=test,dc=example,dc=com']})],
8,
[])
*** <lib389.DirSrv instance at 0x7f9625f6d2d8>
ldap://localhost.localdomain:54321/ - DirSrv.set_option
((18, []), {})
=> result:
None
Printing my values of resp_data, decoded_resp_ctrls:
[('cn=testgroup,dc=example,dc=com', {'objectClass': ['top', 'extensibleobject'],
'uniqueMember': ['uid=test,dc=example,dc=com'], 'cn': ['testgroup']})]
[]
Where should I go from here to continue to investigate this? I'm not seeing any
calls into my decodeControlValue function on the control, so I suspect either I
haven't registered my DereferenceControl correctly to be used for responses, or
the response is "going missing" at some stage. Doing this same deref with
ldapsearch -E yields a correct response, so it's not a server issue as I can
see.
Your advice is appreciated.
Sincerely,
William
[0] https://tools.ietf.org/html/draft-masarati-ldap-deref-00
[1]:
from pyasn1.type import namedtype,univ
from pyasn1.codec.ber import encoder,decoder
from pyasn1_modules.rfc2251 import AttributeDescription
# Could use AttributeDescriptionList
"""
controlValue ::= SEQUENCE OF derefSpec DerefSpec
DerefSpec ::= SEQUENCE {
derefAttr attributeDescription, ; with DN syntax
attributes AttributeList }
AttributeList ::= SEQUENCE OF attr AttributeDescription
Needs to be matched by ber_scanf(ber, "{a{v}}", ... )
"""
CONTROL_DEREF = '1.3.6.1.4.1.4203.666.5.16'
class AttributeList(univ.SequenceOf):
componentType = AttributeDescription()
class DerefSpec(univ.Sequence):
componentType = namedtype.NamedTypes(
namedtype.NamedType('derefAttr', AttributeDescription()),
namedtype.NamedType('attributes', AttributeList()),
)
class DerefControlValue(univ.SequenceOf):
componentType = DerefSpec()
class DereferenceControl(LDAPControl):
"""
Dereference Control
"""
def __init__(self, criticality, deref):
LDAPControl.__init__(self, CONTROL_DEREF, criticality)
self.deref = deref
def encodeControlValue(self):
cv = DerefControlValue()
cvi = 0
for derefSpec in self.deref.split(';'):
derefAttr, attributes = derefSpec.split(':')
attributes = attributes.split(',')
al = AttributeList()
i = 0
while len(attributes) > 0:
al.setComponentByPosition(i, attributes.pop())
i += 1
ds = DerefSpec()
ds.setComponentByName('derefAttr', derefAttr)
ds.setComponentByName('attributes', al)
cv.setComponentByPosition(cvi, ds)
cvi += 1
print(cv.prettyPrint())
return encoder.encode(cv)
def decodeControlValue(self,encodedControlValue):
print('DEREF decode')
print(encodedControlValue)
More information about the python-ldap
mailing list