def test_bind_noMatchingServicesFound_fallback_success(self): server = self.createServer( services=['svc1', 'svc2', 'svc3', ], fallback=True, responses=[ [ pureldap.LDAPSearchResultDone(ldaperrors.Success.resultCode) ], [ pureldap.LDAPSearchResultDone(ldaperrors.Success.resultCode) ], [ pureldap.LDAPSearchResultDone(ldaperrors.Success.resultCode) ], [ pureldap.LDAPBindResponse(resultCode=ldaperrors.Success.resultCode) ], ]) server.dataReceived(str(pureldap.LDAPMessage(pureldap.LDAPBindRequest(dn='cn=jack,dc=example,dc=com', auth='s3krit'), id=4))) reactor.iterate() #TODO client = server.client client.assertSent( pureldap.LDAPSearchRequest(baseObject='dc=example,dc=com', derefAliases=0, sizeLimit=0, timeLimit=0, typesOnly=0, filter=ldapfilter.parseFilter('(&' +'(objectClass=serviceSecurityObject)' +'(owner=cn=jack,dc=example,dc=com)' +'(cn=svc1)' +('(|(!(validFrom=*))(validFrom<=%s))' % server.now) +('(|(!(validUntil=*))(validUntil>=%s))' % server.now) +')'), attributes=('1.1',)), pureldap.LDAPSearchRequest(baseObject='dc=example,dc=com', derefAliases=0, sizeLimit=0, timeLimit=0, typesOnly=0, filter=ldapfilter.parseFilter('(&' +'(objectClass=serviceSecurityObject)' +'(owner=cn=jack,dc=example,dc=com)' +'(cn=svc2)' +('(|(!(validFrom=*))(validFrom<=%s))' % server.now) +('(|(!(validUntil=*))(validUntil>=%s))' % server.now) +')'), attributes=('1.1',)), pureldap.LDAPSearchRequest(baseObject='dc=example,dc=com', derefAliases=0, sizeLimit=0, timeLimit=0, typesOnly=0, filter=ldapfilter.parseFilter('(&' +'(objectClass=serviceSecurityObject)' +'(owner=cn=jack,dc=example,dc=com)' +'(cn=svc3)' +('(|(!(validFrom=*))(validFrom<=%s))' % server.now) +('(|(!(validUntil=*))(validUntil>=%s))' % server.now) +')'), attributes=('1.1',)), pureldap.LDAPBindRequest(dn='cn=jack,dc=example,dc=com', auth='s3krit')) self.assertEquals(server.transport.value(), str(pureldap.LDAPMessage(pureldap.LDAPBindResponse(resultCode=ldaperrors.Success.resultCode), id=4)))
def _cb_testSimple(self, val, client): client.assertSent( pureldap.LDAPSearchRequest( baseObject='dc=example,dc=com', scope=pureldap.LDAP_SCOPE_baseObject, derefAliases=pureldap.LDAP_DEREF_neverDerefAliases, sizeLimit=1, timeLimit=0, typesOnly=0, filter=pureldap.LDAPFilter_present('objectClass'), attributes=['subschemaSubentry']), pureldap.LDAPSearchRequest( baseObject='cn=Subschema', scope=pureldap.LDAP_SCOPE_baseObject, derefAliases=pureldap.LDAP_DEREF_neverDerefAliases, sizeLimit=1, timeLimit=0, typesOnly=0, filter=pureldap.LDAPFilter_present('objectClass'), attributes=['attributeTypes', 'objectClasses']), ) self.failUnlessEqual(len(val), 2) self.failUnlessEqual([str(x) for x in val[0]], [str(schema.AttributeTypeDescription(self.cn))]) self.failUnlessEqual( [str(x) for x in val[1]], [str(schema.ObjectClassDescription(self.dcObject))])
def _cb_testSimple(self, val, client): client.assertSent( pureldap.LDAPSearchRequest( baseObject="dc=example,dc=com", scope=pureldap.LDAP_SCOPE_baseObject, derefAliases=pureldap.LDAP_DEREF_neverDerefAliases, sizeLimit=1, timeLimit=0, typesOnly=0, filter=pureldap.LDAPFilter_present("objectClass"), attributes=["subschemaSubentry"], ), pureldap.LDAPSearchRequest( baseObject="cn=Subschema", scope=pureldap.LDAP_SCOPE_baseObject, derefAliases=pureldap.LDAP_DEREF_neverDerefAliases, sizeLimit=1, timeLimit=0, typesOnly=0, filter=pureldap.LDAPFilter_present("objectClass"), attributes=["attributeTypes", "objectClasses"], ), ) self.failUnlessEqual(len(val), 2) self.failUnlessEqual( [to_bytes(x) for x in val[0]], [to_bytes(schema.AttributeTypeDescription(self.cn))], ) self.failUnlessEqual( [to_bytes(x) for x in val[1]], [to_bytes(schema.ObjectClassDescription(self.dcObject))], )
def _cb_testDefaultSetting(self, val, client, o): client.assertSent( *[ pureldap.LDAPSearchRequest( baseObject='dc=example,dc=com', scope=2, derefAliases=0, sizeLimit=1, timeLimit=0, typesOnly=0, filter=pureldap.LDAPFilter_equalityMatch(attributeDesc=pureldap.LDAPAttributeDescription(value='uidNumber'), assertionValue=pureldap.LDAPAssertionValue(value='1000')), attributes=()), ] + [ pureldap.LDAPSearchRequest( baseObject='dc=example,dc=com', scope=2, derefAliases=0, sizeLimit=1, timeLimit=0, typesOnly=0, filter=pureldap.LDAPFilter_equalityMatch(attributeDesc=pureldap.LDAPAttributeDescription(value='gidNumber'), assertionValue=pureldap.LDAPAssertionValue(value=str(x))), attributes=()) for x in (1000, 1500, 1250, 1125, 1062, 1031, 1046, 1038, 1042, 1040, 1041)]) self.failUnless('loginShell' in o) self.failUnlessEqual(o['loginShell'], ['/bin/sh']) self.failUnless('uidNumber' in o) self.failUnlessEqual(o['uidNumber'], ['1000']) self.failUnless('gidNumber' in o) self.failUnlessEqual(o['gidNumber'], ['1042'])
def _cb_testDefaultSetting(self, val, client, o): client.assertSent(*[ pureldap.LDAPSearchRequest( baseObject="dc=example,dc=com", scope=2, derefAliases=0, sizeLimit=1, timeLimit=0, typesOnly=0, filter=pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( value="uidNumber"), assertionValue=pureldap.LDAPAssertionValue(value="1000"), ), attributes=(), ), ] + [ pureldap.LDAPSearchRequest( baseObject="dc=example,dc=com", scope=2, derefAliases=0, sizeLimit=1, timeLimit=0, typesOnly=0, filter=pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( value="gidNumber"), assertionValue=pureldap.LDAPAssertionValue(value=str(x)), ), attributes=(), ) for x in ( 1000, 1500, 1250, 1125, 1062, 1031, 1046, 1038, 1042, 1040, 1041, ) ]) self.failUnless("loginShell" in o) self.failUnlessEqual(o["loginShell"], ["/bin/sh"]) self.failUnless("uidNumber" in o) self.failUnlessEqual(o["uidNumber"], ["1000"]) self.failUnless("gidNumber" in o) self.failUnlessEqual(o["gidNumber"], ["1042"])
def test_search_matchAll_manyResults(self): self.server.dataReceived( str( pureldap.LDAPMessage(pureldap.LDAPSearchRequest( baseObject='ou=stuff,dc=example,dc=com'), id=2))) six.assertCountEqual( self, [ str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( objectName='ou=stuff,dc=example,dc=com', attributes=[('objectClass', ['a', 'b']), ('ou', ['stuff'])]), id=2)), str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( objectName='cn=another,ou=stuff,dc=example,dc=com', attributes=[('objectClass', ['a', 'b']), ('cn', ['another'])]), id=2)), str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( objectName='cn=thingie,ou=stuff,dc=example,dc=com', attributes=[('objectClass', ['a', 'b']), ('cn', ['thingie'])]), id=2)), str( pureldap.LDAPMessage( pureldap.LDAPSearchResultDone(resultCode=0), id=2)) ], self._makeResultList(self.server.transport.value()))
def test_search(self): """ When performing an LDAP search against the server; the search results and a single "search done" response is written to the transport. """ server = self.createServer( [pureldap.LDAPBindResponse(resultCode=0)], [ pureldap.LDAPSearchResultEntry('cn=foo,dc=example,dc=com', [('a', ['b'])]), pureldap.LDAPSearchResultEntry('cn=bar,dc=example,dc=com', [('b', ['c'])]), pureldap.LDAPSearchResultDone(ldaperrors.Success.resultCode) ], ) server.dataReceived( pureldap.LDAPMessage(pureldap.LDAPBindRequest(), id=2).toWire()) server.dataReceived( pureldap.LDAPMessage(pureldap.LDAPSearchRequest(), id=3).toWire()) server.reactor.advance(1) self.assertEqual( server.transport.value(), pureldap.LDAPMessage(pureldap.LDAPBindResponse(resultCode=0), id=2).toWire() + pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( 'cn=foo,dc=example,dc=com', [('a', ['b'])]), id=3).toWire() + pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( 'cn=bar,dc=example,dc=com', [('b', ['c'])]), id=3).toWire() + pureldap.LDAPMessage(pureldap.LDAPSearchResultDone( ldaperrors.Success.resultCode), id=3).toWire())
def test_search(self): server = self.createServer( [ pureldap.LDAPBindResponse(resultCode=0), ], [ pureldap.LDAPSearchResultEntry('cn=foo,dc=example,dc=com', [('a', ['b'])]), pureldap.LDAPSearchResultEntry('cn=bar,dc=example,dc=com', [('b', ['c'])]), pureldap.LDAPSearchResultDone(ldaperrors.Success.resultCode), ], ) server.dataReceived( str(pureldap.LDAPMessage(pureldap.LDAPBindRequest(), id=2))) server.dataReceived( str(pureldap.LDAPMessage(pureldap.LDAPSearchRequest(), id=3))) reactor.iterate() #TODO self.assertEquals( server.transport.value(), str( pureldap.LDAPMessage( pureldap.LDAPBindResponse(resultCode=0), id=2)) + str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( 'cn=foo,dc=example,dc=com', [('a', ['b'])]), id=3)) + str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( 'cn=bar,dc=example,dc=com', [('b', ['c'])]), id=3)) + str( pureldap.LDAPMessage(pureldap.LDAPSearchResultDone( ldaperrors.Success.resultCode), id=3)))
def test_search_scope_wholeSubtree(self): self.server.dataReceived( str( pureldap.LDAPMessage(pureldap.LDAPSearchRequest( baseObject='ou=stuff,dc=example,dc=com', scope=pureldap.LDAP_SCOPE_wholeSubtree), id=2))) self.assertItemsEqual( self._makeResultList(self.server.transport.value()), [ str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( objectName='ou=stuff,dc=example,dc=com', attributes=[('objectClass', ['a', 'b']), ('ou', ['stuff'])]), id=2)), str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( objectName='cn=another,ou=stuff,dc=example,dc=com', attributes=[('objectClass', ['a', 'b']), ('cn', ['another'])]), id=2)), str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( objectName='cn=thingie,ou=stuff,dc=example,dc=com', attributes=[('objectClass', ['a', 'b']), ('cn', ['thingie'])]), id=2)), str( pureldap.LDAPMessage( pureldap.LDAPSearchResultDone(resultCode=0), id=2)) ])
def test_search(self): server = self.createServer( [ pureldap.LDAPBindResponse(resultCode=0), ], [ pureldap.LDAPSearchResultEntry("cn=foo,dc=example,dc=com", [("a", ["b"])]), pureldap.LDAPSearchResultEntry("cn=bar,dc=example,dc=com", [("b", ["c"])]), pureldap.LDAPSearchResultDone(ldaperrors.Success.resultCode), ], ) server.dataReceived( pureldap.LDAPMessage(pureldap.LDAPBindRequest(), id=2).toWire()) server.dataReceived( pureldap.LDAPMessage(pureldap.LDAPSearchRequest(), id=3).toWire()) reactor.iterate() # TODO self.assertEqual( server.transport.value(), pureldap.LDAPMessage(pureldap.LDAPBindResponse(resultCode=0), id=2).toWire() + pureldap.LDAPMessage( pureldap.LDAPSearchResultEntry("cn=foo,dc=example,dc=com", [("a", ["b"])]), id=3, ).toWire() + pureldap.LDAPMessage( pureldap.LDAPSearchResultEntry("cn=bar,dc=example,dc=com", [("b", ["c"])]), id=3, ).toWire() + pureldap.LDAPMessage(pureldap.LDAPSearchResultDone( ldaperrors.Success.resultCode), id=3).toWire(), )
def test_search_scope_oneLevel(self): self.server.dataReceived( str( pureldap.LDAPMessage(pureldap.LDAPSearchRequest( baseObject='ou=stuff,dc=example,dc=com', scope=pureldap.LDAP_SCOPE_singleLevel, ), id=2))) self.assertEquals( self.server.transport.value(), str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( objectName='cn=thingie,ou=stuff,dc=example,dc=com', attributes=[ ('objectClass', ['a', 'b']), ('cn', ['thingie']), ]), id=2)) + str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( objectName='cn=another,ou=stuff,dc=example,dc=com', attributes=[ ('objectClass', ['a', 'b']), ('cn', ['another']), ]), id=2)) + str( pureldap.LDAPMessage( pureldap.LDAPSearchResultDone(resultCode=0), id=2)), )
def test_intercepted_search_response(self): """ When performing an LDAP search against the server; the search results are intercepted and modified by the proxy. """ server = self.createServer([pureldap.LDAPBindResponse(resultCode=0)], [ pureldap.LDAPSearchResultEntry('cn=foo,dc=example,dc=com', [('a', ['b'])]), pureldap.LDAPSearchResultEntry('cn=bar,dc=example,dc=com', [('b', ['c'])]), pureldap.LDAPSearchResultDone(ldaperrors.Success.resultCode) ], protocol=ResponseInterceptingProxy) server.dataReceived( pureldap.LDAPMessage(pureldap.LDAPBindRequest(), id=2).toWire()) server.dataReceived( pureldap.LDAPMessage(pureldap.LDAPSearchRequest(), id=3).toWire()) server.reactor.advance(1) server.reactor.advance(5) self.assertEqual( server.transport.value(), pureldap.LDAPMessage(pureldap.LDAPBindResponse(resultCode=0), id=2).toWire() + pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( 'cn=foo,dc=example,dc=com', [('a', ['b']), ('frotz', ['xyzzy'])]), id=3).toWire() + pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( 'cn=bar,dc=example,dc=com', [('b', ['c']), ('frotz', ['xyzzy'])]), id=3).toWire() + pureldap.LDAPMessage(pureldap.LDAPSearchResultDone( ldaperrors.Success.resultCode), id=3).toWire())
def test_simple_bind(self): dn = 'uid=thegreathugo,cn=users,dc=test,dc=local' server, client = self.create_server_and_client() service_account_client = self.inject_service_account_server( [ pureldap.LDAPBindResponse(resultCode=0), # for service account ], [ pureldap.LDAPSearchResultEntry(dn, [('sAMAccountName', ['hugo'])]), pureldap.LDAPSearchResultDone(ldaperrors.Success.resultCode), ]) yield client.bind(dn, 'secret') # Assert that Proxy<->Backend (the actual connection) did not send anything server.client.assertNothingSent() # Assert that Proxy<->Backend (the lookup connection) did send something service_account_client.assertSent( pureldap.LDAPBindRequest( dn='uid=service,cn=users,dc=test,dc=local', auth='service-secret'), pureldap.LDAPSearchRequest( baseObject='uid=thegreathugo,cn=users,dc=test,dc=local', scope=0, derefAliases=0, sizeLimit=0, timeLimit=0, typesOnly=0, filter=pureldap.LDAPFilter_present(value='objectClass'), attributes=()), 'fake-unbind-by-LDAPClientTestDriver')
def makeSearch( self, baseObject=None, scope=None, derefAliases=None, sizeLimit=None, timeLimit=None, typesOnly=None, filter=None, attributes=None, tag=None, ): """Shortcut for sending LDAPSearchRequest to the test server""" self.server.dataReceived( pureldap.LDAPMessage( pureldap.LDAPSearchRequest( baseObject=baseObject, scope=scope, derefAliases=derefAliases, sizeLimit=sizeLimit, timeLimit=timeLimit, typesOnly=typesOnly, filter=filter, attributes=attributes, tag=tag, ), id=2, ).toWire())
def test_rootDSE(self): self.server.dataReceived( str( pureldap.LDAPMessage(pureldap.LDAPSearchRequest( baseObject='', scope=pureldap.LDAP_SCOPE_baseObject, filter=pureldap.LDAPFilter_present('objectClass'), ), id=2))) self.assertEquals( self.server.transport.value(), str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( objectName='', attributes=[ ('supportedLDAPVersion', ['3']), ('namingContexts', ['dc=example,dc=com']), ('supportedExtension', [ pureldap.LDAPPasswordModifyRequest.oid, ]), ]), id=2)) + str( pureldap.LDAPMessage(pureldap.LDAPSearchResultDone( resultCode=ldaperrors.Success.resultCode), id=2)), )
def test_intercepted_search_request(self): """ When performing an LDAP search against the server; the requests are intercepted and custom responses are written to the transport. """ server = self.createServer([pureldap.LDAPBindResponse(resultCode=0)], [ pureldap.LDAPSearchResultEntry('cn=foo,dc=example,dc=com', [('a', ['b'])]), pureldap.LDAPSearchResultEntry('cn=bar,dc=example,dc=com', [('b', ['c'])]), pureldap.LDAPSearchResultDone(ldaperrors.Success.resultCode), ], protocol=RequestInterceptingProxy) server.responses = [ pureldap.LDAPSearchResultEntry('cn=xyzzy,dc=example,dc=com', [('frobnitz', ['zork'])]), pureldap.LDAPSearchResultDone(ldaperrors.Success.resultCode) ] server.dataReceived( str(pureldap.LDAPMessage(pureldap.LDAPSearchRequest(), id=1))) server.reactor.advance(1) self.assertEqual(len(server.clientTestDriver.sent), 0) self.assertEqual( server.transport.value(), str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( 'cn=xyzzy,dc=example,dc=com', [('frobnitz', ['zork'])]), id=1)) + str( pureldap.LDAPMessage(pureldap.LDAPSearchResultDone( ldaperrors.Success.resultCode), id=1)))
def create_test_search_req(self): """ Create a test LDAP search request. """ basedn = "ou=people,dc=example,dc=org" scope = pureldap.LDAP_SCOPE_wholeSubtree op = pureldap.LDAPSearchRequest(basedn, scope) return op
def search(self, filterText=None, filterObject=None, attributes=(), scope=None, derefAliases=None, sizeLimit=0, sizeLimitIsNonFatal=False, timeLimit=0, typesOnly=0, callback=None): self._checkState() d = defer.Deferred() if filterObject is None and filterText is None: filterObject = pureldap.LDAPFilterMatchAll elif filterObject is None and filterText is not None: filterObject = ldapfilter.parseFilter(filterText) elif filterObject is not None and filterText is None: pass elif filterObject is not None and filterText is not None: f = ldapfilter.parseFilter(filterText) filterObject = pureldap.LDAPFilter_and((f, filterObject)) if scope is None: scope = pureldap.LDAP_SCOPE_wholeSubtree if derefAliases is None: derefAliases = pureldap.LDAP_DEREF_neverDerefAliases if attributes is None: attributes = ['1.1'] results = [] if callback is None: cb = results.append else: cb = callback try: op = pureldap.LDAPSearchRequest(baseObject=str(self.dn), scope=scope, derefAliases=derefAliases, sizeLimit=sizeLimit, timeLimit=timeLimit, typesOnly=typesOnly, filter=filterObject, attributes=attributes) self.client.send_multiResponse( op, self._cbSearchMsg, d, cb, complete=not attributes, sizeLimitIsNonFatal=sizeLimitIsNonFatal) except ldapclient.LDAPClientConnectionLostException: d.errback(Failure()) else: if callback is None: d.addCallback(lambda dummy: results) return d
def test_search_matchAll_oneResult_filteredNoAttribsRemaining(self): self.server.dataReceived( str( pureldap.LDAPMessage(pureldap.LDAPSearchRequest( baseObject='cn=thingie,ou=stuff,dc=example,dc=com', attributes=['xyzzy']), id=2))) self.assertEquals( self.server.transport.value(), str( pureldap.LDAPMessage( pureldap.LDAPSearchResultDone(resultCode=0), id=2)))
def test_search_outOfTree(self): self.server.dataReceived( str( pureldap.LDAPMessage( pureldap.LDAPSearchRequest(baseObject='dc=invalid'), id=2))) self.assertEquals( self.server.transport.value(), str( pureldap.LDAPMessage(pureldap.LDAPSearchResultDone( resultCode=ldaperrors.LDAPNoSuchObject.resultCode), id=2)))
def test_detect_login_preamble(self): filter = parseFilter( '(&(|(objectclass=person)(objectclass=App-someApp))(cn=user123))') request = pureldap.LDAPSearchRequest( baseObject='cn=users,dc=test,dc=local', scope=pureldap.LDAP_SCOPE_wholeSubtree, derefAliases=0, sizeLimit=0, timeLimit=0, typesOnly=0, filter=filter, attributes=()) dn = 'cn=user123,cn=users,dc=test,dc=local' response = pureldap.LDAPSearchResultEntry(dn, [('cn', ['user123'])]) self.assertEqual(detect_login_preamble(request, response), (dn, 'someApp')) self.assertIsNone( detect_login_preamble(request, pureldap.LDAPSearchResultDone(0))) filter = parseFilter( '(&(|(objectclass=person)(someATTRIBuTE=Foo-someApp))(cn=user123))' ) request = pureldap.LDAPSearchRequest( baseObject='cn=users,dc=test,dc=local', scope=pureldap.LDAP_SCOPE_wholeSubtree, derefAliases=0, sizeLimit=0, timeLimit=0, typesOnly=0, filter=filter, attributes=()) dn = 'cn=user123,cn=users,dc=test,dc=local' response = pureldap.LDAPSearchResultEntry(dn, [('cn', ['user123'])]) self.assertEqual( detect_login_preamble(request, response, 'someAttribute', 'Foo-'), (dn, 'someApp'))
def test_message_repr(self): page_size = 10 cookie = "xyzzy" control_value = pureber.BERSequence([ pureber.BERInteger(page_size), pureber.BEROctetString(cookie), ]) controls = [('1.2.840.113556.1.4.319', None, control_value)] search_request = pureldap.LDAPSearchRequest( "cn=foo,ou=baz,dc=example,dc=org") ldap_msg = pureldap.LDAPMessage(id=1, value=search_request, controls=controls, tag=1) expected_value = "LDAPMessage(id=1, value=LDAPSearchRequest(baseObject='cn=foo,ou=baz,dc=example,dc=org', scope=2, derefAliases=0, sizeLimit=0, timeLimit=0, typesOnly=0, filter=LDAPFilter_present(value='objectClass'), attributes=[]), controls=[('1.2.840.113556.1.4.319', None, BERSequence(value=[BERInteger(value=10), BEROctetString(value='xyzzy')]))], tag=1)" self.assertEqual(expected_value, repr(ldap_msg))
def test_search_matchAll_oneResult(self): self.server.dataReceived( str( pureldap.LDAPMessage(pureldap.LDAPSearchRequest( baseObject='cn=thingie,ou=stuff,dc=example,dc=com'), id=2))) self.assertEquals( self.server.transport.value(), str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( objectName='cn=thingie,ou=stuff,dc=example,dc=com', attributes=[('objectClass', ['a', 'b']), ('cn', ['thingie'])]), id=2)) + str( pureldap.LDAPMessage( pureldap.LDAPSearchResultDone(resultCode=0), id=2)))
def test_search_matchAll_oneResult_filtered(self): self.server.dataReceived( str( pureldap.LDAPMessage(pureldap.LDAPSearchRequest( baseObject='cn=thingie,ou=stuff,dc=example,dc=com', attributes=['cn']), id=2))) self.assertItemsEqual( self._makeResultList(self.server.transport.value()), [ str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( objectName='cn=thingie,ou=stuff,dc=example,dc=com', attributes=[('cn', ['thingie'])]), id=2)), str( pureldap.LDAPMessage( pureldap.LDAPSearchResultDone(resultCode=0), id=2)) ])
def test_search_scope_baseObject(self): self.server.dataReceived( str( pureldap.LDAPMessage(pureldap.LDAPSearchRequest( baseObject='ou=stuff,dc=example,dc=com', scope=pureldap.LDAP_SCOPE_baseObject), id=2))) self.assertEquals( self.server.transport.value(), str( pureldap.LDAPMessage(pureldap.LDAPSearchResultEntry( objectName='ou=stuff,dc=example,dc=com', attributes=[('objectClass', ['a', 'b']), ('ou', ['stuff'])]), id=2)) + str( pureldap.LDAPMessage( pureldap.LDAPSearchResultDone(resultCode=0), id=2)))
def search(self, filterText=None, filterObject=None, attributes=(), scope=None, derefAliases=None, sizeLimit=0, sizeLimitIsNonFatal=False, timeLimit=0, typesOnly=0, callback=None, controls=None, return_controls=False): self._checkState() d = defer.Deferred() if filterObject is None and filterText is None: filterObject = pureldap.LDAPFilterMatchAll elif filterObject is None and filterText is not None: filterObject = ldapfilter.parseFilter(filterText) elif filterObject is not None and filterText is None: pass elif filterObject is not None and filterText is not None: f = ldapfilter.parseFilter(filterText) filterObject = pureldap.LDAPFilter_and((f, filterObject)) if scope is None: scope = pureldap.LDAP_SCOPE_wholeSubtree if derefAliases is None: derefAliases = pureldap.LDAP_DEREF_neverDerefAliases if attributes is None: attributes = ['1.1'] results = [] if callback is None: cb = results.append else: cb = callback try: op = pureldap.LDAPSearchRequest(baseObject=self.dn.getText(), scope=scope, derefAliases=derefAliases, sizeLimit=sizeLimit, timeLimit=timeLimit, typesOnly=typesOnly, filter=filterObject, attributes=attributes) dsend = self.client.send_multiResponse_ex( op, controls, self._cbSearchMsg, d, cb, complete=not attributes, sizeLimitIsNonFatal=sizeLimitIsNonFatal) except ldapclient.LDAPClientConnectionLostException: d.errback(Failure()) else: if callback is None: if return_controls: d.addCallback(lambda ctls: (results, ctls)) else: d.addCallback(lambda dummy: results) def rerouteerr(e): d.errback(e) # returning None will stop the error # from being propagated and logged. dsend.addErrback(rerouteerr) return d
def _paged_search( self, client, base_dn, filter_text, attributes, pagination=PAGINATION_TYPE_CRITICAL, max_result_size=None, page_size=DEFAULT_PAGE_SIZE, ): """ Given a bound client, search exhaustively using RFC 2696. Return a list of dictionaries containing the attributes of the resulting entries. * attributes: Set of lower-case byte-strings. """ res = [] def handle_msg(value, controls, d): try: if isinstance(value, pureldap.LDAPSearchResultDone): e = ldaperrors.get(value.resultCode, value.errorMessage) if isinstance(e, (ldaperrors.Success, ldaperrors.LDAPSizeLimitExceeded)): cookie = get_cookie(controls) d.callback((None, cookie)) else: d.callback((e, None)) elif isinstance(value, pureldap.LDAPSearchResultEntry): # Always send DN. Overwrite DN from attribute set, if any. obj = { "distinguishedname": [escape_bytes(value.objectName)] } for k, vs in value.attributes: # Smash attribute name case. k = k.decode().lower() # Server may not honor attributes (e.g. # SearchByTreeWalkingMixin). if attributes and k.encode() not in attributes: continue # Covert value to list and encode for JSON. vs = [escape_bytes(v) for v in vs] obj[k] = vs # Refuse to return certain attributes even if all # attributes were requested. obj.pop("userpassword", None) res.append(obj) except Exception: log.failure("Unexpected error handling message") finally: return isinstance(value, ( pureldap.LDAPBindResponse, pureldap.LDAPSearchResultDone, )) if filter_text: filter_obj = ldapfilter.parseFilter(filter_text) else: filter_obj = None op = pureldap.LDAPSearchRequest( baseObject=base_dn, scope=pureldap.LDAP_SCOPE_wholeSubtree, derefAliases=0, sizeLimit=0, timeLimit=0, typesOnly=0, filter=filter_obj, attributes=attributes, ) if pagination == PAGINATION_TYPE_CRITICAL: # AD may ignore the RFC 2696 control if it is not # critical. The caller can override this default if the # control should be present but not critical or absent. criticality = True else: criticality = False cookie = pureber.BEROctetString("") while True: if pagination == PAGINATION_TYPE_DISABLE: controls = None else: controls = [ ( RFC_2696_CONTROL_TYPE, criticality, pureber.BERSequence([ pureber.BERInteger(page_size), cookie, ]), ), ] d = defer.Deferred() yield client.send( op=op, controls=controls, handler=functools.partial(handle_msg, d=d), return_controls=True, ) # handle_msg() is synchronous so d should be called by the # time it returns to LDAPClient.handle(). if d.called: e, cookie = yield d else: log.error("Paging cookie not found!") break if e is not None: # So the RPC caller can distinguish between problems # with the search (e.g. bad configuration) and # searches that return no results. if isinstance(e, ldaperrors.LDAPOperationsError ) and e.message.decode().startswith( const.LDAP_SUCCESSFUL_BIND_NEEDED_ERROR): raise ldap.client.ConnectionNotProperlyBoundError( "Search failed because either there was no bind on this connection or there were insufficient privileges with the bound user. If you are attempting to use integrated authentication with SSPI please make sure the server running the Authentication Proxy is domain joined." ) else: raise e if not cookie.value: break if max_result_size is not None and len(res) > max_result_size: break defer.returnValue(res)
class KnownValues(unittest.TestCase): knownValues = ( # class, args, kwargs, expected_result (pureldap.LDAPModifyRequest, [], { "object": 'cn=foo, dc=example, dc=com', "modification": [ pureber.BERSequence([ pureber.BEREnumerated(0), pureber.BERSequence([ pureldap.LDAPAttributeDescription('bar'), pureber.BERSet([ pureldap.LDAPString('a'), pureldap.LDAPString('b'), ]), ]), ]), ], }, None, [0x66, 50] + ([0x04, 0x1a] + l("cn=foo, dc=example, dc=com") + [0x30, 20] + ([0x30, 18] + ([0x0a, 0x01, 0x00] + [0x30, 13] + ([0x04, len("bar")] + l("bar") + [0x31, 0x06] + ([0x04, len("a")] + l("a") + [0x04, len("b")] + l("b"))))))), (pureldap.LDAPModifyRequest, [], { "object": 'cn=foo, dc=example, dc=com', "modification": [ pureber.BERSequence([ pureber.BEREnumerated(1L), pureber.BERSequence([ pureber.BEROctetString('bar'), pureber.BERSet([]), ]), ]), ], }, None, [0x66, 0x2c] + ([0x04, 0x1a] + l("cn=foo, dc=example, dc=com") + [0x30, 0x0e] + ([0x30, 0x0c] + ([0x0a, 0x01, 0x01] + [0x30, 0x07] + ([0x04, 0x03] + l("bar") + [0x31, 0x00]))))), (pureldap.LDAPFilter_not, [], { "value": pureldap.LDAPFilter_present("foo"), }, pureldap.LDAPBERDecoderContext_Filter( fallback=pureber.BERDecoderContext()), [0xa2, 0x05] + [0x87] + [len("foo")] + l("foo")), ( pureldap.LDAPFilter_or, [], { "value": [ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( value='cn'), assertionValue=pureldap.LDAPAssertionValue( value='foo')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( value='uid'), assertionValue=pureldap.LDAPAssertionValue( value='foo')), ] }, pureldap.LDAPBERDecoderContext_Filter( fallback=pureber.BERDecoderContext()), [0xa1, 23] + [0xa3, 9] + [0x04] + [len("cn")] + l("cn") + [0x04] + [len("foo")] + l("foo") + [0xa3, 10] + [0x04] + [len("uid")] + l("uid") + [0x04] + [len("foo")] + l("foo"), ), ( pureldap.LDAPFilter_and, [], { "value": [ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( value='cn'), assertionValue=pureldap.LDAPAssertionValue( value='foo')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( value='uid'), assertionValue=pureldap.LDAPAssertionValue( value='foo')), ] }, pureldap.LDAPBERDecoderContext_Filter( fallback=pureber.BERDecoderContext()), [0xa0, 23] + [0xa3, 9] + [0x04] + [len("cn")] + l("cn") + [0x04] + [len("foo")] + l("foo") + [0xa3, 10] + [0x04] + [len("uid")] + l("uid") + [0x04] + [len("foo")] + l("foo"), ), (pureldap.LDAPModifyDNRequest, [], { 'entry': 'cn=foo,dc=example,dc=com', 'newrdn': 'uid=bar', 'deleteoldrdn': 0, }, None, [0x6c, 0x26] + [0x04] + [len("cn=foo,dc=example,dc=com")] + l("cn=foo,dc=example,dc=com") + [0x04] + [len("uid=bar")] + l("uid=bar") + [0x01, 0x01, 0x00]), (pureldap.LDAPModifyDNRequest, [], { 'entry': 'cn=aoue,dc=example,dc=com', 'newrdn': 'uid=aoue', 'deleteoldrdn': 0, 'newSuperior': 'ou=People,dc=example,dc=com', }, None, [0x6c, 69] + [0x04] + [len("cn=aoue,dc=example,dc=com")] + l("cn=aoue,dc=example,dc=com") + [0x04] + [len("uid=aoue")] + l("uid=aoue") + [0x01, 0x01, 0x00] + [0x80] + [len("ou=People,dc=example,dc=com")] + l("ou=People,dc=example,dc=com")), ( pureldap.LDAPSearchRequest, [], { 'baseObject': 'dc=yoja,dc=example,dc=com', }, None, [0x63, 57] + [0x04] + [len('dc=yoja,dc=example,dc=com')] + l('dc=yoja,dc=example,dc=com') # scope + [0x0a, 1, 2] # derefAliases + [0x0a, 1, 0] # sizeLimit + [0x02, 1, 0] # timeLimit + [0x02, 1, 0] # typesOnly + [0x01, 1, 0] # filter + [135, 11] + l('objectClass') # attributes + [48, 0]), (pureldap.LDAPUnbindRequest, [], {}, None, [0x42, 0x00]), ( pureldap.LDAPSearchResultDone, [], { 'resultCode': 0, }, None, [0x65, 0x07] # resultCode + [0x0a, 0x01, 0x00] # matchedDN + [0x04] + [len('')] + l('') # errorMessage + [0x04] + [len('')] + l('') # referral, TODO + []), ( pureldap.LDAPSearchResultDone, [], { 'resultCode': 0, 'matchedDN': 'dc=foo,dc=example,dc=com', }, None, [0x65, 31] # resultCode + [0x0a, 0x01, 0x00] # matchedDN + [0x04] + [len('dc=foo,dc=example,dc=com')] + l('dc=foo,dc=example,dc=com') # errorMessage + [0x04] + [len('')] + l('') # referral, TODO + []), ( pureldap.LDAPSearchResultDone, [], { 'resultCode': 0, 'matchedDN': 'dc=foo,dc=example,dc=com', 'errorMessage': 'the foobar was fubar', }, None, [0x65, 51] # resultCode + [0x0a, 0x01, 0x00] # matchedDN + [0x04] + [len('dc=foo,dc=example,dc=com')] + l('dc=foo,dc=example,dc=com') # errorMessage + [0x04] + [len('the foobar was fubar')] + l('the foobar was fubar', ) # referral, TODO + []), ( pureldap.LDAPSearchResultDone, [], { 'resultCode': 0, 'errorMessage': 'the foobar was fubar', }, None, [0x65, 27] # resultCode + [0x0a, 0x01, 0x00] # matchedDN + [0x04] + [len('')] + l('') # errorMessage + [0x04] + [len('the foobar was fubar')] + l('the foobar was fubar', ) # referral, TODO + []), ( pureldap.LDAPMessage, [], { 'id': 42, 'value': pureldap.LDAPBindRequest(), }, pureldap.LDAPBERDecoderContext_TopLevel( inherit=pureldap.LDAPBERDecoderContext_LDAPMessage( fallback=pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext()), inherit=pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext()))), [0x30, 12] # id + [0x02, 0x01, 42] # value + l(str(pureldap.LDAPBindRequest()))), ( pureldap.LDAPControl, [], { 'controlType': '1.2.3.4', }, None, [0x30, 9] # controlType + [0x04, 7] + l("1.2.3.4")), ( pureldap.LDAPControl, [], { 'controlType': '1.2.3.4', 'criticality': True, }, None, [0x30, 12] # controlType + [0x04, 7] + l("1.2.3.4") # criticality + [0x01, 1, 0xFF]), ( pureldap.LDAPControl, [], { 'controlType': '1.2.3.4', 'criticality': True, 'controlValue': 'silly', }, None, [0x30, 19] # controlType + [0x04, 7] + l("1.2.3.4") # criticality + [0x01, 1, 0xFF] # controlValue + [0x04, len("silly")] + l("silly")), ( pureldap.LDAPMessage, [], { 'id': 42, 'value': pureldap.LDAPBindRequest(), 'controls': [ ('1.2.3.4', None, None), ('2.3.4.5', False), ('3.4.5.6', True, '\x00\x01\x02\xFF'), ], }, pureldap.LDAPBERDecoderContext_TopLevel( inherit=pureldap.LDAPBERDecoderContext_LDAPMessage( fallback=pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext()), inherit=pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext()))), [0x30, 59] # id + [0x02, 0x01, 42] # value + l(str(pureldap.LDAPBindRequest())) # controls + l( str( pureldap.LDAPControls(value=[ pureldap.LDAPControl(controlType='1.2.3.4'), pureldap.LDAPControl(controlType='2.3.4.5', criticality=False), pureldap.LDAPControl(controlType='3.4.5.6', criticality=True, controlValue='\x00\x01\x02\xFF'), ]))), ), (pureldap.LDAPFilter_equalityMatch, [], { 'attributeDesc': pureldap.LDAPAttributeDescription('cn'), 'assertionValue': pureldap.LDAPAssertionValue('foo'), }, pureldap.LDAPBERDecoderContext_Filter( fallback=pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext()), inherit=pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext())), [0xa3, 9] + ([0x04, 2] + l('cn') + [0x04, 3] + l('foo'))), (pureldap.LDAPFilter_or, [[ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('cn'), assertionValue=pureldap.LDAPAssertionValue('foo')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('uid'), assertionValue=pureldap.LDAPAssertionValue('foo')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('mail'), assertionValue=pureldap.LDAPAssertionValue('foo')), pureldap.LDAPFilter_substrings( type='mail', substrings=[pureldap.LDAPFilter_substrings_initial('foo@')]), ]], {}, pureldap.LDAPBERDecoderContext_Filter( fallback=pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext()), inherit=pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext())), [0xA1, 52] + ([0xa3, 9] + ([0x04, 2] + l('cn') + [0x04, 3] + l('foo')) + [0xa3, 10] + ([0x04, 3] + l('uid') + [0x04, 3] + l('foo')) + [0xa3, 11] + ([0x04, 4] + l('mail') + [0x04, 3] + l('foo')) + [0xa4, 14] + ([0x04, 4] + l('mail') + [0x30, 6] + ([0x80, 4] + l('foo@'))))), (pureldap.LDAPSearchRequest, [], { 'baseObject': 'dc=example,dc=com', 'scope': pureldap.LDAP_SCOPE_wholeSubtree, 'derefAliases': pureldap.LDAP_DEREF_neverDerefAliases, 'sizeLimit': 1, 'timeLimit': 0, 'typesOnly': False, 'filter': pureldap.LDAPFilter_or([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('cn'), assertionValue=pureldap.LDAPAssertionValue('foo')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('uid'), assertionValue=pureldap.LDAPAssertionValue('foo')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('mail'), assertionValue=pureldap.LDAPAssertionValue('foo')), pureldap.LDAPFilter_substrings( type='mail', substrings=[ pureldap.LDAPFilter_substrings_initial('foo@') ]), ]), 'attributes': [''], }, pureldap.LDAPBERDecoderContext_LDAPMessage( fallback=pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext()), inherit=pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext())), [0x63, 92] + ([0x04, 17] + l('dc=example,dc=com') + [0x0a, 1, 0x02] + [0x0a, 1, 0x00] + [0x02, 1, 0x01] + [0x02, 1, 0x00] + [0x01, 1, 0x00] + [0xA1, 52] + ([0xa3, 9] + ([0x04, 2] + l('cn') + [0x04, 3] + l('foo')) + [0xa3, 10] + ([0x04, 3] + l('uid') + [0x04, 3] + l('foo')) + [0xa3, 11] + ([0x04, 4] + l('mail') + [0x04, 3] + l('foo')) + [0xa4, 14] + ([0x04, 4] + l('mail') + [0x30, 6] + ([0x80, 4] + l('foo@')))) + [0x30, 2] + ([0x04, 0]))), ( pureldap.LDAPMessage, [], { 'id': 1L, 'value': pureldap.LDAPSearchRequest( baseObject='dc=example,dc=com', scope=pureldap.LDAP_SCOPE_wholeSubtree, derefAliases=pureldap.LDAP_DEREF_neverDerefAliases, sizeLimit=1, timeLimit=0, typesOnly=False, filter=pureldap.LDAPFilter_or([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( 'cn'), assertionValue=pureldap.LDAPAssertionValue('foo')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( 'uid'), assertionValue=pureldap.LDAPAssertionValue('foo')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( 'mail'), assertionValue=pureldap.LDAPAssertionValue('foo')), pureldap.LDAPFilter_substrings( type='mail', substrings=[ pureldap.LDAPFilter_substrings_initial('foo@') ]), ]), attributes=[''], ), }, pureldap.LDAPBERDecoderContext_TopLevel( inherit=pureldap.LDAPBERDecoderContext_LDAPMessage( fallback=pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext()), inherit=pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext()))), [0x30, 97] # id + [0x02, 1, 1] # value + [0x63, 92] + ([0x04, 17] + l('dc=example,dc=com') + [0x0a, 1, 0x02] + [0x0a, 1, 0x00] + [0x02, 1, 0x01] + [0x02, 1, 0x00] + [0x01, 1, 0x00] + [0xA1, 52] + ([0xa3, 9] + ([0x04, 2] + l('cn') + [0x04, 3] + l('foo')) + [0xa3, 10] + ([0x04, 3] + l('uid') + [0x04, 3] + l('foo')) + [0xa3, 11] + ([0x04, 4] + l('mail') + [0x04, 3] + l('foo')) + [0xa4, 14] + ([0x04, 4] + l('mail') + [0x30, 6] + ([0x80, 4] + l('foo@')))) + [0x30, 2] + ([0x04, 0]))), (pureldap.LDAPExtendedRequest, [], { 'requestName': '42.42.42', 'requestValue': 'foo', }, None, [0x40 | 0x20 | 23, 1 + 1 + 8 + 1 + 1 + 3] + ([0x80 | 0] + [len('42.42.42')] + l('42.42.42')) + ([0x80 | 1] + [len('foo')] + l('foo'))), ) def testToLDAP(self): """str(LDAPClass(...)) should give known result with known input""" for klass, args, kwargs, decoder, encoded in self.knownValues: result = klass(*args, **kwargs) result = str(result) result = map(ord, result) if result != encoded: raise AssertionError, \ "Class %s(*%s, **%s) doesn't encode properly: " \ "%s != %s" % (klass.__name__, repr(args), repr(kwargs), repr(result), repr(encoded)) def testFromLDAP(self): """LDAPClass(encoded="...") should give known result with known input""" for klass, args, kwargs, decoder, encoded in self.knownValues: if decoder is None: decoder = pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext()) m = s(*encoded) result, bytes = pureber.berDecodeObject(decoder, m) self.assertEquals(bytes, len(m)) shouldBe = klass(*args, **kwargs) #TODO shouldn't use str below assert str(result)==str(shouldBe), \ "Class %s(*%s, **%s) doesn't decode properly: " \ "%s != %s" % (klass.__name__, repr(args), repr(kwargs), repr(result), repr(shouldBe)) def testPartial(self): """LDAPClass(encoded="...") with too short input should throw BERExceptionInsufficientData""" for klass, args, kwargs, decoder, encoded in self.knownValues: if decoder is None: decoder = pureldap.LDAPBERDecoderContext( fallback=pureber.BERDecoderContext()) for i in xrange(1, len(encoded)): m = s(*encoded)[:i] self.assertRaises(pureber.BERExceptionInsufficientData, pureber.berDecodeObject, decoder, m) self.assertEquals((None, 0), pureber.berDecodeObject(decoder, ''))
def test_bind_match_badAuth(self): server = self.createServer( services=[ 'svc1', 'svc2', 'svc3', ], fallback=True, responses=[ # svc1 [ pureldap.LDAPSearchResultEntry( r'cn=svc1+owner=cn\=jack\,dc\=example\,dc\=com,dc=example,dc=com', attributes=[]), pureldap.LDAPSearchResultDone( ldaperrors.Success.resultCode) ], [ pureldap.LDAPBindResponse( resultCode=ldaperrors.LDAPInvalidCredentials.resultCode ) ], # svc2 [pureldap.LDAPSearchResultDone(ldaperrors.Success.resultCode)], # svc3 [ pureldap.LDAPSearchResultEntry( r'cn=svc3+owner=cn\=jack\,dc\=example\,dc\=com,dc=example,dc=com', attributes=[]), pureldap.LDAPSearchResultDone( ldaperrors.Success.resultCode) ], [ pureldap.LDAPBindResponse( resultCode=ldaperrors.LDAPInvalidCredentials.resultCode ) ], [ pureldap.LDAPBindResponse( resultCode=ldaperrors.LDAPInvalidCredentials.resultCode ) ], ]) server.dataReceived( pureldap.LDAPMessage(pureldap.LDAPBindRequest( dn='cn=jack,dc=example,dc=com', auth='wrong-s3krit'), id=4).toWire()) reactor.iterate() #TODO client = server.client client.assertSent( pureldap.LDAPSearchRequest( baseObject='dc=example,dc=com', derefAliases=0, sizeLimit=0, timeLimit=0, typesOnly=0, filter=ldapfilter.parseFilter( '(&' + '(objectClass=serviceSecurityObject)' + '(owner=cn=jack,dc=example,dc=com)' + '(cn=svc1)' + ('(|(!(validFrom=*))(validFrom<=%s))' % server.now) + ('(|(!(validUntil=*))(validUntil>=%s))' % server.now) + ')'), attributes=('1.1', )), pureldap.LDAPBindRequest( dn= r'cn=svc1+owner=cn\=jack\,dc\=example\,dc\=com,dc=example,dc=com', auth='wrong-s3krit'), pureldap.LDAPSearchRequest( baseObject='dc=example,dc=com', derefAliases=0, sizeLimit=0, timeLimit=0, typesOnly=0, filter=ldapfilter.parseFilter( '(&' + '(objectClass=serviceSecurityObject)' + '(owner=cn=jack,dc=example,dc=com)' + '(cn=svc2)' + ('(|(!(validFrom=*))(validFrom<=%s))' % server.now) + ('(|(!(validUntil=*))(validUntil>=%s))' % server.now) + ')'), attributes=('1.1', )), pureldap.LDAPSearchRequest( baseObject='dc=example,dc=com', derefAliases=0, sizeLimit=0, timeLimit=0, typesOnly=0, filter=ldapfilter.parseFilter( '(&' + '(objectClass=serviceSecurityObject)' + '(owner=cn=jack,dc=example,dc=com)' + '(cn=svc3)' + ('(|(!(validFrom=*))(validFrom<=%s))' % server.now) + ('(|(!(validUntil=*))(validUntil>=%s))' % server.now) + ')'), attributes=('1.1', )), pureldap.LDAPBindRequest( dn= 'cn=svc3+owner=cn\=jack\,dc\=example\,dc\=com,dc=example,dc=com', auth='wrong-s3krit'), pureldap.LDAPBindRequest(version=3, dn='cn=jack,dc=example,dc=com', auth='wrong-s3krit'), ) self.assertEqual( server.transport.value(), pureldap.LDAPMessage(pureldap.LDAPBindResponse( resultCode=ldaperrors.LDAPInvalidCredentials.resultCode), id=4).toWire())