Blame SOURCES/0047-Issue-5984-Crash-when-paged-result-search-are-abando.patch

183893
From 53cecf3abcc08724ae9b21fd02b8423fd39e7086 Mon Sep 17 00:00:00 2001
183893
From: progier389 <progier@redhat.com>
183893
Date: Fri, 17 Nov 2023 14:41:51 +0100
183893
Subject: [PATCH] Issue 5984 - Crash when paged result search are abandoned -
183893
 fix + fix2 (#5985 and #5987)
183893
183893
Notice: This cherry-pick include two commit:
183893
df7dd8320 Issue 5984 - Crash when paged result search are abandoned - fix2 (#5987)
183893
06bd08629 Issue 5984 - Crash when paged result search are abandoned (#5985)
183893
The reason is that cherry pick of #5985 generates lots of conflict in __init.py
183893
 and #5987 only revert that file ==> So it is easier and safer to keep the original
183893
  file.
183893
183893
* Issue 5984 - Crash when paged result search are abandoned
183893
183893
Problem:
183893
  Fix #4551 has changed the lock that protects the paged result data
183893
  within a connection. But the abandon operation attempts to free
183893
  the paged search result with the connection lock.
183893
  This leads to race condition and double free causing an heap
183893
  corruption and a SIGSEGV.
183893
183893
  Solution:
183893
   - Get a copy of the operation data that needs to be logged.
183893
   - Unlock the connection mutex (to avoid deadlock risk)
183893
   - Free the paged result while holding the paged result lock.
183893
183893
Issue: 5984
183893
183893
Reviewed by: @tbordaz (Thanks!)
183893
183893
(cherry picked from commit 06bd0862956672eb76276cab5c1dd906fe5a7eec)
183893
---
183893
 .../paged_results/paged_results_test.py       | 758 +++++++++---------
183893
 ldap/servers/slapd/abandon.c                  |  23 +-
183893
 ldap/servers/slapd/opshared.c                 |   4 +-
183893
 ldap/servers/slapd/pagedresults.c             |   8 +-
183893
 ldap/servers/slapd/proto-slap.h               |   2 +-
183893
 5 files changed, 392 insertions(+), 403 deletions(-)
183893
183893
diff --git a/dirsrvtests/tests/suites/paged_results/paged_results_test.py b/dirsrvtests/tests/suites/paged_results/paged_results_test.py
183893
index ae2627b75..a030824c6 100644
183893
--- a/dirsrvtests/tests/suites/paged_results/paged_results_test.py
183893
+++ b/dirsrvtests/tests/suites/paged_results/paged_results_test.py
183893
@@ -1,21 +1,32 @@
183893
 # --- BEGIN COPYRIGHT BLOCK ---
183893
-# Copyright (C) 2016 Red Hat, Inc.
183893
+# Copyright (C) 2020 Red Hat, Inc.
183893
 # All rights reserved.
183893
 #
183893
 # License: GPL (version 3 or any later version).
183893
 # See LICENSE for details.
183893
 # --- END COPYRIGHT BLOCK ---
183893
 #
183893
-from random import sample
183893
+import socket
183893
+from random import sample, randrange
183893
 
183893
 import pytest
183893
 from ldap.controls import SimplePagedResultsControl, GetEffectiveRightsControl
183893
 from lib389.tasks import *
183893
 from lib389.utils import *
183893
 from lib389.topologies import topology_st
183893
-from lib389._constants import DN_LDBM, DN_DM, DEFAULT_SUFFIX, BACKEND_NAME, PASSWORD
183893
+from lib389._constants import DN_LDBM, DN_DM, DEFAULT_SUFFIX
183893
+from lib389._controls import SSSRequestControl
183893
+from lib389.idm.user import UserAccount, UserAccounts
183893
+from lib389.cli_base import FakeArgs
183893
+from lib389.config import LDBMConfig
183893
+from lib389.dbgen import dbgen_users
183893
 
183893
-from sss_control import SSSRequestControl
183893
+from lib389.idm.organization import Organization
183893
+from lib389.idm.organizationalunit import OrganizationalUnit
183893
+from lib389.backend import Backends
183893
+from lib389._mapped_object import DSLdapObject
183893
+
183893
+pytestmark = pytest.mark.tier1
183893
 
183893
 DEBUGGING = os.getenv('DEBUGGING', False)
183893
 
183893
@@ -26,9 +37,8 @@ else:
183893
 
183893
 log = logging.getLogger(__name__)
183893
 
183893
-TEST_USER_NAME = 'simplepaged_test'
183893
-TEST_USER_DN = 'uid={},{}'.format(TEST_USER_NAME, DEFAULT_SUFFIX)
183893
 TEST_USER_PWD = 'simplepaged_test'
183893
+
183893
 NEW_SUFFIX_1_NAME = 'test_parent'
183893
 NEW_SUFFIX_1 = 'o={}'.format(NEW_SUFFIX_1_NAME)
183893
 NEW_SUFFIX_2_NAME = 'child'
183893
@@ -36,34 +46,90 @@ NEW_SUFFIX_2 = 'ou={},{}'.format(NEW_SUFFIX_2_NAME, NEW_SUFFIX_1)
183893
 NEW_BACKEND_1 = 'parent_base'
183893
 NEW_BACKEND_2 = 'child_base'
183893
 
183893
+OLD_HOSTNAME = socket.gethostname()
183893
+if os.getuid() == 0:
183893
+    socket.sethostname('localhost')
183893
+HOSTNAME = socket.gethostname()
183893
+IP_ADDRESS = socket.gethostbyname(HOSTNAME)
183893
+OLD_IP_ADDRESS = socket.gethostbyname(OLD_HOSTNAME)
183893
+
183893
 
183893
 @pytest.fixture(scope="module")
183893
-def test_user(topology_st, request):
183893
+def create_40k_users(topology_st, request):
183893
+    inst = topology_st.standalone
183893
+
183893
+    # Prepare return value
183893
+    retval = FakeArgs()
183893
+    retval.inst = inst
183893
+    retval.bename = '40k'
183893
+    retval.suffix = 'o=%s' % retval.bename
183893
+    ldifdir = inst.get_ldif_dir()
183893
+    retval.ldif_file = '%s/%s.ldif' % (ldifdir, retval.bename)
183893
+
183893
+    # Create new backend
183893
+    bes = Backends(inst)
183893
+    be_1 = bes.create(properties={
183893
+        'cn': retval.bename,
183893
+        'nsslapd-suffix': retval.suffix,
183893
+    })
183893
+
183893
+    # Set paged search lookthrough limit
183893
+    ldbmconfig = LDBMConfig(inst)
183893
+    ldbmconfig.replace('nsslapd-pagedlookthroughlimit', b'100000')
183893
+
183893
+    # Create ldif and import it.
183893
+    dbgen_users(inst, 40000, retval.ldif_file, retval.suffix)
183893
+    # tasks = Tasks(inst)
183893
+    # args = {TASK_WAIT: True}
183893
+    # tasks.importLDIF(retval.suffix, None, retval.ldif_file, args)
183893
+    inst.stop()
183893
+    assert inst.ldif2db(retval.bename, None, None, None, retval.ldif_file, None)
183893
+    inst.start()
183893
+
183893
+    # And set an aci allowing anonymous read
183893
+    log.info('Adding ACI to allow our test user to search')
183893
+    ACI_TARGET = '(targetattr != "userPassword || aci")'
183893
+    ACI_ALLOW = '(version 3.0; acl "Enable anonymous access";allow (read, search, compare)'
183893
+    ACI_SUBJECT = '(userdn = "ldap:///anyone");)'
183893
+    ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
183893
+    o_1 = Organization(inst, retval.suffix)
183893
+    o_1.set('aci', ACI_BODY)
183893
+
183893
+    return retval
183893
+
183893
+
183893
+@pytest.fixture(scope="module")
183893
+def create_user(topology_st, request):
183893
     """User for binding operation"""
183893
 
183893
-    log.info('Adding user {}'.format(TEST_USER_DN))
183893
-    try:
183893
-        topology_st.standalone.add_s(Entry((TEST_USER_DN, {
183893
-            'objectclass': 'top person'.split(),
183893
-            'objectclass': 'organizationalPerson',
183893
-            'objectclass': 'inetorgperson',
183893
-            'cn': TEST_USER_NAME,
183893
-            'sn': TEST_USER_NAME,
183893
-            'userpassword': TEST_USER_PWD,
183893
-            'mail': '%s@redhat.com' % TEST_USER_NAME,
183893
-            'uid': TEST_USER_NAME
183893
-        })))
183893
-    except ldap.LDAPError as e:
183893
-        log.error('Failed to add user (%s): error (%s)' % (TEST_USER_DN,
183893
-                                                           e.message['desc']))
183893
-        raise e
183893
+    log.info('Adding user simplepaged_test')
183893
+    new_uri = topology_st.standalone.ldapuri.replace(OLD_HOSTNAME, HOSTNAME)
183893
+    topology_st.standalone.ldapuri = new_uri
183893
+    users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX)
183893
+    user = users.create(properties={
183893
+        'uid': 'simplepaged_test',
183893
+        'cn': 'simplepaged_test',
183893
+        'sn': 'simplepaged_test',
183893
+        'uidNumber': '1234',
183893
+        'gidNumber': '1234',
183893
+        'homeDirectory': '/home/simplepaged_test',
183893
+        'userPassword': TEST_USER_PWD,
183893
+    })
183893
+
183893
+    # Now add the ACI so simplepage_test can read the users ...
183893
+    ACI_BODY = ensure_bytes('(targetattr= "uid || sn || dn")(version 3.0; acl "Allow read for user"; allow (read,search,compare) userdn = "ldap:///all";)')
183893
+    topology_st.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_REPLACE, 'aci', ACI_BODY)])
183893
 
183893
     def fin():
183893
-        log.info('Deleting user {}'.format(TEST_USER_DN))
183893
-        topology_st.standalone.delete_s(TEST_USER_DN)
183893
+        log.info('Deleting user simplepaged_test')
183893
+        if not DEBUGGING:
183893
+            user.delete()
183893
+        if os.getuid() == 0:
183893
+            socket.sethostname(OLD_HOSTNAME)
183893
 
183893
     request.addfinalizer(fin)
183893
 
183893
+    return user
183893
 
183893
 @pytest.fixture(scope="module")
183893
 def new_suffixes(topology_st):
183893
@@ -72,47 +138,40 @@ def new_suffixes(topology_st):
183893
     """
183893
 
183893
     log.info('Adding suffix:{} and backend: {}'.format(NEW_SUFFIX_1, NEW_BACKEND_1))
183893
-    topology_st.standalone.backend.create(NEW_SUFFIX_1,
183893
-                                          {BACKEND_NAME: NEW_BACKEND_1})
183893
-    topology_st.standalone.mappingtree.create(NEW_SUFFIX_1,
183893
-                                              bename=NEW_BACKEND_1)
183893
-    try:
183893
-        topology_st.standalone.add_s(Entry((NEW_SUFFIX_1, {
183893
-            'objectclass': 'top',
183893
-            'objectclass': 'organization',
183893
-            'o': NEW_SUFFIX_1_NAME
183893
-        })))
183893
-    except ldap.LDAPError as e:
183893
-        log.error('Failed to add suffix ({}): error ({})'.format(NEW_SUFFIX_1,
183893
-                                                                 e.message['desc']))
183893
-        raise
183893
 
183893
-    log.info('Adding suffix:{} and backend: {}'.format(NEW_SUFFIX_2, NEW_BACKEND_2))
183893
-    topology_st.standalone.backend.create(NEW_SUFFIX_2,
183893
-                                          {BACKEND_NAME: NEW_BACKEND_2})
183893
-    topology_st.standalone.mappingtree.create(NEW_SUFFIX_2,
183893
-                                              bename=NEW_BACKEND_2,
183893
-                                              parent=NEW_SUFFIX_1)
183893
-
183893
-    try:
183893
-        topology_st.standalone.add_s(Entry((NEW_SUFFIX_2, {
183893
-            'objectclass': 'top',
183893
-            'objectclass': 'organizationalunit',
183893
-            'ou': NEW_SUFFIX_2_NAME
183893
-        })))
183893
-    except ldap.LDAPError as e:
183893
-        log.error('Failed to add suffix ({}): error ({})'.format(NEW_SUFFIX_2,
183893
-                                                                 e.message['desc']))
183893
-        raise
183893
+    bes = Backends(topology_st.standalone)
183893
 
183893
+    bes.create(properties={
183893
+        'cn': 'NEW_BACKEND_1',
183893
+        'nsslapd-suffix': NEW_SUFFIX_1,
183893
+    })
183893
+    # Create the root objects with their ACI
183893
     log.info('Adding ACI to allow our test user to search')
183893
     ACI_TARGET = '(targetattr != "userPassword || aci")'
183893
     ACI_ALLOW = '(version 3.0; acl "Enable anonymous access";allow (read, search, compare)'
183893
     ACI_SUBJECT = '(userdn = "ldap:///anyone");)'
183893
     ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
183893
 
183893
-    mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
183893
-    topology_st.standalone.modify_s(NEW_SUFFIX_1, mod)
183893
+    o_1 = Organization(topology_st.standalone, NEW_SUFFIX_1)
183893
+    o_1.create(properties={
183893
+        'o': NEW_SUFFIX_1_NAME,
183893
+        'aci': ACI_BODY,
183893
+    })
183893
+
183893
+    log.info('Adding suffix:{} and backend: {}'.format(NEW_SUFFIX_2, NEW_BACKEND_2))
183893
+    be_2 = bes.create(properties={
183893
+        'cn': 'NEW_BACKEND_2',
183893
+        'nsslapd-suffix': NEW_SUFFIX_2,
183893
+    })
183893
+
183893
+    # We have to adjust the MT to say that BE_1 is a parent.
183893
+    mt = be_2.get_mapping_tree()
183893
+    mt.set_parent(NEW_SUFFIX_1)
183893
+
183893
+    ou_2 = OrganizationalUnit(topology_st.standalone, NEW_SUFFIX_2)
183893
+    ou_2.create(properties={
183893
+        'ou': NEW_SUFFIX_2_NAME
183893
+    })
183893
 
183893
 
183893
 def add_users(topology_st, users_num, suffix):
183893
@@ -122,72 +181,54 @@ def add_users(topology_st, users_num, suffix):
183893
     """
183893
 
183893
     users_list = []
183893
+    users = UserAccounts(topology_st.standalone, suffix, rdn=None)
183893
+
183893
     log.info('Adding %d users' % users_num)
183893
     for num in sample(range(1000), users_num):
183893
         num_ran = int(round(num))
183893
         USER_NAME = 'test%05d' % num_ran
183893
-        USER_DN = 'uid=%s,%s' % (USER_NAME, suffix)
183893
-        users_list.append(USER_DN)
183893
-        try:
183893
-            topology_st.standalone.add_s(Entry((USER_DN, {
183893
-                'objectclass': 'top person'.split(),
183893
-                'objectclass': 'organizationalPerson',
183893
-                'objectclass': 'inetorgperson',
183893
-                'cn': USER_NAME,
183893
-                'sn': USER_NAME,
183893
-                'userpassword': 'pass%s' % num_ran,
183893
-                'mail': '%s@redhat.com' % USER_NAME,
183893
-                'uid': USER_NAME})))
183893
-        except ldap.LDAPError as e:
183893
-            log.error('Failed to add user (%s): error (%s)' % (USER_DN,
183893
-                                                               e.message['desc']))
183893
-            raise e
183893
+
183893
+        user = users.create(properties={
183893
+            'uid': USER_NAME,
183893
+            'sn': USER_NAME,
183893
+            'cn': USER_NAME,
183893
+            'uidNumber': '%s' % num_ran,
183893
+            'gidNumber': '%s' % num_ran,
183893
+            'homeDirectory': '/home/%s' % USER_NAME,
183893
+            'mail': '%s@redhat.com' % USER_NAME,
183893
+            'userpassword': 'pass%s' % num_ran,
183893
+        })
183893
+        users_list.append(user)
183893
     return users_list
183893
 
183893
 
183893
-def del_users(topology_st, users_list):
183893
+def del_users(users_list):
183893
     """Delete users with DNs from given list"""
183893
 
183893
     log.info('Deleting %d users' % len(users_list))
183893
-    for user_dn in users_list:
183893
-        try:
183893
-            topology_st.standalone.delete_s(user_dn)
183893
-        except ldap.LDAPError as e:
183893
-            log.error('Failed to delete user (%s): error (%s)' % (user_dn,
183893
-                                                                  e.message['desc']))
183893
-            raise e
183893
+    for user in users_list:
183893
+        user.delete()
183893
 
183893
 
183893
 def change_conf_attr(topology_st, suffix, attr_name, attr_value):
183893
-    """Change configurational attribute in the given suffix.
183893
+    """Change configuration attribute in the given suffix.
183893
 
183893
     Returns previous attribute value.
183893
     """
183893
 
183893
-    try:
183893
-        entries = topology_st.standalone.search_s(suffix, ldap.SCOPE_BASE,
183893
-                                                  'objectclass=top',
183893
-                                                  [attr_name])
183893
-        attr_value_bck = entries[0].data.get(attr_name)
183893
-        log.info('Set %s to %s. Previous value - %s. Modified suffix - %s.' % (
183893
-            attr_name, attr_value, attr_value_bck, suffix))
183893
-        if attr_value is None:
183893
-            topology_st.standalone.modify_s(suffix, [(ldap.MOD_DELETE,
183893
-                                                      attr_name,
183893
-                                                      attr_value)])
183893
-        else:
183893
-            topology_st.standalone.modify_s(suffix, [(ldap.MOD_REPLACE,
183893
-                                                      attr_name,
183893
-                                                      attr_value)])
183893
-    except ldap.LDAPError as e:
183893
-        log.error('Failed to change attr value (%s): error (%s)' % (attr_name,
183893
-                                                                    e.message['desc']))
183893
-        raise e
183893
+    entry = DSLdapObject(topology_st.standalone, suffix)
183893
 
183893
+    attr_value_bck = entry.get_attr_val_bytes(attr_name)
183893
+    log.info('Set %s to %s. Previous value - %s. Modified suffix - %s.' % (
183893
+        attr_name, attr_value, attr_value_bck, suffix))
183893
+    if attr_value is None:
183893
+        entry.remove_all(attr_name)
183893
+    else:
183893
+        entry.replace(attr_name, attr_value)
183893
     return attr_value_bck
183893
 
183893
 
183893
-def paged_search(topology_st, suffix, controls, search_flt, searchreq_attrlist):
183893
+def paged_search(conn, suffix, controls, search_flt, searchreq_attrlist, abandon_rate=0):
183893
     """Search at the DEFAULT_SUFFIX with ldap.SCOPE_SUBTREE
183893
     using Simple Paged Control(should the first item in the
183893
     list controls.
183893
@@ -206,14 +247,17 @@ def paged_search(topology_st, suffix, controls, search_flt, searchreq_attrlist):
183893
                                                     searchreq_attrlist,
183893
                                                     req_pr_ctrl.size,
183893
                                                     str(controls)))
183893
-    msgid = topology_st.standalone.search_ext(suffix,
183893
-                                              ldap.SCOPE_SUBTREE,
183893
-                                              search_flt,
183893
-                                              searchreq_attrlist,
183893
-                                              serverctrls=controls)
183893
+    msgid = conn.search_ext(suffix, ldap.SCOPE_SUBTREE, search_flt, searchreq_attrlist, serverctrls=controls)
183893
+    log.info('Getting page %d' % (pages,))
183893
     while True:
183893
-        log.info('Getting page %d' % (pages,))
183893
-        rtype, rdata, rmsgid, rctrls = topology_st.standalone.result3(msgid)
183893
+        try:
183893
+            rtype, rdata, rmsgid, rctrls = conn.result3(msgid, timeout=0.001)
183893
+        except ldap.TIMEOUT:
183893
+            if pages > 0 and abandon_rate>0 and randrange(100)
183893
+                conn.abandon(msgid)
183893
+                log.info('Paged result search is abandonned.')
183893
+                return all_results
183893
+            continue
183893
         log.debug('Data: {}'.format(rdata))
183893
         all_results.extend(rdata)
183893
         pages += 1
183893
@@ -228,27 +272,25 @@ def paged_search(topology_st, suffix, controls, search_flt, searchreq_attrlist):
183893
                 # Copy cookie from response control to request control
183893
                 log.debug('Cookie: {}'.format(pctrls[0].cookie))
183893
                 req_pr_ctrl.cookie = pctrls[0].cookie
183893
-                msgid = topology_st.standalone.search_ext(suffix,
183893
-                                                          ldap.SCOPE_SUBTREE,
183893
-                                                          search_flt,
183893
-                                                          searchreq_attrlist,
183893
-                                                          serverctrls=controls)
183893
+                msgid = conn.search_ext(suffix, ldap.SCOPE_SUBTREE, search_flt, searchreq_attrlist, serverctrls=controls)
183893
             else:
183893
                 break  # No more pages available
183893
         else:
183893
             break
183893
+        log.info('Getting page %d' % (pages,))
183893
 
183893
     assert not pctrls[0].cookie
183893
     return all_results
183893
 
183893
 
183893
-@pytest.mark.parametrize("page_size,users_num",
183893
-                         [(6, 5), (5, 5), (5, 25)])
183893
-def test_search_success(topology_st, test_user, page_size, users_num):
183893
+@pytest.mark.parametrize("page_size,users_num", [(6, 5), (5, 5), (5, 25)])
183893
+def test_search_success(topology_st, create_user, page_size, users_num):
183893
     """Verify that search with a simple paged results control
183893
     returns all entries it should without errors.
183893
 
183893
     :id: ddd15b70-64f1-4a85-a793-b24761e50354
183893
+    :customerscenario: True
183893
+    :parametrized: yes
183893
     :feature: Simple paged results
183893
     :setup: Standalone instance, test user for binding,
183893
             varying number of users for the search base
183893
@@ -264,21 +306,16 @@ def test_search_success(topology_st, test_user, page_size, users_num):
183893
     search_flt = r'(uid=test*)'
183893
     searchreq_attrlist = ['dn', 'sn']
183893
 
183893
-    try:
183893
-        log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+    log.info('Set user bind %s ' % create_user)
183893
+    conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
-        req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
+    req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
+    all_results = paged_search(conn, DEFAULT_SUFFIX, [req_ctrl], search_flt, searchreq_attrlist)
183893
 
183893
-        all_results = paged_search(topology_st, DEFAULT_SUFFIX, [req_ctrl],
183893
-                                   search_flt, searchreq_attrlist)
183893
+    log.info('%d results' % len(all_results))
183893
+    assert len(all_results) == len(users_list)
183893
 
183893
-        log.info('%d results' % len(all_results))
183893
-        assert len(all_results) == len(users_list)
183893
-    finally:
183893
-        log.info('Set Directory Manager bind back (test_search_success)')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
+    del_users(users_list)
183893
 
183893
 
183893
 @pytest.mark.parametrize("page_size,users_num,suffix,attr_name,attr_value,expected_err", [
183893
@@ -292,13 +329,15 @@ def test_search_success(topology_st, test_user, page_size, users_num):
183893
      ldap.SIZELIMIT_EXCEEDED),
183893
     (5, 50, 'cn=config,%s' % DN_LDBM, 'nsslapd-lookthroughlimit', '20',
183893
      ldap.ADMINLIMIT_EXCEEDED)])
183893
-def test_search_limits_fail(topology_st, test_user, page_size, users_num,
183893
+def test_search_limits_fail(topology_st, create_user, page_size, users_num,
183893
                             suffix, attr_name, attr_value, expected_err):
183893
     """Verify that search with a simple paged results control
183893
     throws expected exceptoins when corresponding limits are
183893
     exceeded.
183893
 
183893
     :id: e3067107-bd6d-493d-9989-3e641a9337b0
183893
+    :customerscenario: True
183893
+    :parametrized: yes
183893
     :setup: Standalone instance, test user for binding,
183893
             varying number of users for the search base
183893
     :steps:
183893
@@ -321,7 +360,7 @@ def test_search_limits_fail(topology_st, test_user, page_size, users_num,
183893
 
183893
     try:
183893
         log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
         log.info('Create simple paged results control instance')
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
@@ -330,11 +369,8 @@ def test_search_limits_fail(topology_st, test_user, page_size, users_num,
183893
             sort_ctrl = SSSRequestControl(True, ['sn'])
183893
             controls.append(sort_ctrl)
183893
         log.info('Initiate ldapsearch with created control instance')
183893
-        msgid = topology_st.standalone.search_ext(DEFAULT_SUFFIX,
183893
-                                                  ldap.SCOPE_SUBTREE,
183893
-                                                  search_flt,
183893
-                                                  searchreq_attrlist,
183893
-                                                  serverctrls=controls)
183893
+        msgid = conn.search_ext(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,
183893
+                                search_flt, searchreq_attrlist, serverctrls=controls)
183893
 
183893
         time_val = conf_param_dict.get('nsslapd-timelimit')
183893
         if time_val:
183893
@@ -345,12 +381,11 @@ def test_search_limits_fail(topology_st, test_user, page_size, users_num,
183893
         pctrls = []
183893
         while True:
183893
             log.info('Getting page %d' % (pages,))
183893
-            if pages == 0 and (time_val or attr_name in ('nsslapd-lookthroughlimit',
183893
-                                                         'nsslapd-pagesizelimit')):
183893
-                rtype, rdata, rmsgid, rctrls = topology_st.standalone.result3(msgid)
183893
+            if pages == 0 and (time_val or attr_name == 'nsslapd-pagesizelimit'):
183893
+                rtype, rdata, rmsgid, rctrls = conn.result3(msgid)
183893
             else:
183893
                 with pytest.raises(expected_err):
183893
-                    rtype, rdata, rmsgid, rctrls = topology_st.standalone.result3(msgid)
183893
+                    rtype, rdata, rmsgid, rctrls = conn.result3(msgid)
183893
                     all_results.extend(rdata)
183893
                     pages += 1
183893
                     pctrls = [
183893
@@ -363,28 +398,24 @@ def test_search_limits_fail(topology_st, test_user, page_size, users_num,
183893
                 if pctrls[0].cookie:
183893
                     # Copy cookie from response control to request control
183893
                     req_ctrl.cookie = pctrls[0].cookie
183893
-                    msgid = topology_st.standalone.search_ext(DEFAULT_SUFFIX,
183893
-                                                              ldap.SCOPE_SUBTREE,
183893
-                                                              search_flt,
183893
-                                                              searchreq_attrlist,
183893
-                                                              serverctrls=controls)
183893
+                    msgid = conn.search_ext(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,
183893
+                                            search_flt, searchreq_attrlist, serverctrls=controls)
183893
                 else:
183893
                     break  # No more pages available
183893
             else:
183893
                 break
183893
     finally:
183893
-        log.info('Set Directory Manager bind back (test_search_limits_fail)')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
+        del_users(users_list)
183893
         change_conf_attr(topology_st, suffix, attr_name, attr_value_bck)
183893
 
183893
 
183893
-def test_search_sort_success(topology_st, test_user):
183893
+def test_search_sort_success(topology_st, create_user):
183893
     """Verify that search with a simple paged results control
183893
     and a server side sort control returns all entries
183893
     it should without errors.
183893
 
183893
     :id: 17d8b150-ed43-41e1-b80f-ee9b4ce45155
183893
+    :customerscenario: True
183893
     :setup: Standalone instance, test user for binding,
183893
             varying number of users for the search base
183893
     :steps:
183893
@@ -403,8 +434,7 @@ def test_search_sort_success(topology_st, test_user):
183893
     searchreq_attrlist = ['dn', 'sn']
183893
 
183893
     try:
183893
-        log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
         sort_ctrl = SSSRequestControl(True, ['sn'])
183893
@@ -412,25 +442,25 @@ def test_search_sort_success(topology_st, test_user):
183893
         log.info('Initiate ldapsearch with created control instance')
183893
         log.info('Collect data with sorting')
183893
         controls = [req_ctrl, sort_ctrl]
183893
-        results_sorted = paged_search(topology_st, DEFAULT_SUFFIX, controls,
183893
+        results_sorted = paged_search(conn, DEFAULT_SUFFIX, controls,
183893
                                       search_flt, searchreq_attrlist)
183893
 
183893
         log.info('Substring numbers from user DNs')
183893
-        r_nums = map(lambda x: int(x[0][8:13]), results_sorted)
183893
+        # r_nums = map(lambda x: int(x[0][8:13]), results_sorted)
183893
+        r_nums = [int(x[0][8:13]) for x in results_sorted]
183893
 
183893
         log.info('Assert that list is sorted')
183893
         assert all(r_nums[i] <= r_nums[i + 1] for i in range(len(r_nums) - 1))
183893
     finally:
183893
-        log.info('Set Directory Manager bind back (test_search_sort_success)')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
+        del_users(users_list)
183893
 
183893
 
183893
-def test_search_abandon(topology_st, test_user):
183893
+def test_search_abandon(topology_st, create_user):
183893
     """Verify that search with simple paged results control
183893
     can be abandon
183893
 
183893
     :id: 0008538b-7585-4356-839f-268828066978
183893
+    :customerscenario: True
183893
     :setup: Standalone instance, test user for binding,
183893
             varying number of users for the search base
183893
     :steps:
183893
@@ -452,36 +482,32 @@ def test_search_abandon(topology_st, test_user):
183893
 
183893
     try:
183893
         log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
         log.info('Create simple paged results control instance')
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
         controls = [req_ctrl]
183893
 
183893
         log.info('Initiate a search with a paged results control')
183893
-        msgid = topology_st.standalone.search_ext(DEFAULT_SUFFIX,
183893
-                                                  ldap.SCOPE_SUBTREE,
183893
-                                                  search_flt,
183893
-                                                  searchreq_attrlist,
183893
-                                                  serverctrls=controls)
183893
+        msgid = conn.search_ext(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,
183893
+                                search_flt, searchreq_attrlist, serverctrls=controls)
183893
         log.info('Abandon the search')
183893
-        topology_st.standalone.abandon(msgid)
183893
+        conn.abandon(msgid)
183893
 
183893
         log.info('Expect an ldap.TIMEOUT exception, while trying to get the search results')
183893
         with pytest.raises(ldap.TIMEOUT):
183893
-            topology_st.standalone.result3(msgid, timeout=5)
183893
+            conn.result3(msgid, timeout=5)
183893
     finally:
183893
-        log.info('Set Directory Manager bind back (test_search_abandon)')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
+        del_users(users_list)
183893
 
183893
 
183893
-def test_search_with_timelimit(topology_st, test_user):
183893
+def test_search_with_timelimit(topology_st, create_user):
183893
     """Verify that after performing multiple simple paged searches
183893
     to completion, each with a timelimit, it wouldn't fail, if we sleep
183893
     for a time more than the timelimit.
183893
 
183893
     :id: 6cd7234b-136c-419f-bf3e-43aa73592cff
183893
+    :customerscenario: True
183893
     :setup: Standalone instance, test user for binding,
183893
             varying number of users for the search base
183893
     :steps:
183893
@@ -506,7 +532,7 @@ def test_search_with_timelimit(topology_st, test_user):
183893
 
183893
     try:
183893
         log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
         log.info('Create simple paged results control instance')
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
@@ -514,18 +540,14 @@ def test_search_with_timelimit(topology_st, test_user):
183893
 
183893
         for ii in range(3):
183893
             log.info('Iteration %d' % ii)
183893
-            msgid = topology_st.standalone.search_ext(DEFAULT_SUFFIX,
183893
-                                                      ldap.SCOPE_SUBTREE,
183893
-                                                      search_flt,
183893
-                                                      searchreq_attrlist,
183893
-                                                      serverctrls=controls,
183893
-                                                      timeout=timelimit)
183893
+            msgid = conn.search_ext(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, search_flt,
183893
+                                    searchreq_attrlist, serverctrls=controls, timeout=timelimit)
183893
 
183893
             pages = 0
183893
             pctrls = []
183893
             while True:
183893
                 log.info('Getting page %d' % (pages,))
183893
-                rtype, rdata, rmsgid, rctrls = topology_st.standalone.result3(msgid)
183893
+                rtype, rdata, rmsgid, rctrls = conn.result3(msgid)
183893
                 pages += 1
183893
                 pctrls = [
183893
                     c
183893
@@ -537,12 +559,8 @@ def test_search_with_timelimit(topology_st, test_user):
183893
                     if pctrls[0].cookie:
183893
                         # Copy cookie from response control to request control
183893
                         req_ctrl.cookie = pctrls[0].cookie
183893
-                        msgid = topology_st.standalone.search_ext(DEFAULT_SUFFIX,
183893
-                                                                  ldap.SCOPE_SUBTREE,
183893
-                                                                  search_flt,
183893
-                                                                  searchreq_attrlist,
183893
-                                                                  serverctrls=controls,
183893
-                                                                  timeout=timelimit)
183893
+                        msgid = conn.search_ext(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, search_flt,
183893
+                                                searchreq_attrlist, serverctrls=controls, timeout=timelimit)
183893
                     else:
183893
                         log.info('Done with this search - sleeping %d seconds' % (
183893
                             timelimit * 2))
183893
@@ -551,24 +569,21 @@ def test_search_with_timelimit(topology_st, test_user):
183893
                 else:
183893
                     break
183893
     finally:
183893
-        log.info('Set Directory Manager bind back (test_search_with_timelimit)')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
+        del_users(users_list)
183893
 
183893
 
183893
-@pytest.mark.parametrize('aci_subject',
183893
-                         ('dns = "localhost.localdomain"',
183893
-                          'ip = "::1" or ip = "127.0.0.1"'))
183893
-def test_search_dns_ip_aci(topology_st, test_user, aci_subject):
183893
+def test_search_ip_aci(topology_st, create_user):
183893
     """Verify that after performing multiple simple paged searches
183893
     to completion on the suffix with DNS or IP based ACI
183893
 
183893
     :id: bbfddc46-a8c8-49ae-8c90-7265d05b22a9
183893
+    :customerscenario: True
183893
+    :parametrized: yes
183893
     :setup: Standalone instance, test user for binding,
183893
             varying number of users for the search base
183893
     :steps:
183893
         1. Back up and remove all previous ACI from suffix
183893
-        2. Add an anonymous ACI for DNS check
183893
+        2. Add an anonymous ACI for IP check
183893
         3. Bind as test user
183893
         4. Search through added users with a simple paged control
183893
         5. Perform steps 4 three times in a row
183893
@@ -584,32 +599,31 @@ def test_search_dns_ip_aci(topology_st, test_user, aci_subject):
183893
         6. ACI should be successfully returned
183893
         7. Results should be the same with ACI with IP subject dn
183893
     """
183893
-
183893
-    users_num = 100
183893
+    users_num = 20
183893
     page_size = 5
183893
     users_list = add_users(topology_st, users_num, DEFAULT_SUFFIX)
183893
     search_flt = r'(uid=test*)'
183893
     searchreq_attrlist = ['dn', 'sn']
183893
 
183893
+    log.info("test_search_dns_ip_aci: HOSTNAME: " + HOSTNAME)
183893
+    log.info("test_search_dns_ip_aci: IP_ADDRESS: " + IP_ADDRESS)
183893
+
183893
     try:
183893
         log.info('Back up current suffix ACI')
183893
         acis_bck = topology_st.standalone.aci.list(DEFAULT_SUFFIX, ldap.SCOPE_BASE)
183893
 
183893
         log.info('Add test ACI')
183893
+        bind_rule = 'ip = "{}" or ip = "::1" or ip = "{}"'.format(IP_ADDRESS, OLD_IP_ADDRESS)
183893
         ACI_TARGET = '(targetattr != "userPassword")'
183893
         ACI_ALLOW = '(version 3.0;acl "Anonymous access within domain"; allow (read,compare,search)'
183893
-        ACI_SUBJECT = '(userdn = "ldap:///anyone") and (%s);)' % aci_subject
183893
-        ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
183893
-        try:
183893
-            topology_st.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_REPLACE,
183893
-                                                              'aci',
183893
-                                                              ACI_BODY)])
183893
-        except ldap.LDAPError as e:
183893
-            log.fatal('Failed to add ACI: error (%s)' % (e.message['desc']))
183893
-            raise e
183893
+        ACI_SUBJECT = '(userdn = "ldap:///anyone") and (%s);)' % bind_rule
183893
+        ACI_BODY = ensure_bytes(ACI_TARGET + ACI_ALLOW + ACI_SUBJECT)
183893
+        topology_st.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_REPLACE, 'aci', ACI_BODY)])
183893
+        time.sleep(.5)
183893
 
183893
         log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        myuri = 'ldap://%s:%d' % (HOSTNAME, topology_st.standalone.port)
183893
+        conn = create_user.bind(TEST_USER_PWD, uri=myuri)
183893
 
183893
         log.info('Create simple paged results control instance')
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
@@ -618,31 +632,27 @@ def test_search_dns_ip_aci(topology_st, test_user, aci_subject):
183893
         log.info('Initiate three searches with a paged results control')
183893
         for ii in range(3):
183893
             log.info('%d search' % (ii + 1))
183893
-            all_results = paged_search(topology_st, DEFAULT_SUFFIX, controls,
183893
+            all_results = paged_search(conn, DEFAULT_SUFFIX, controls,
183893
                                        search_flt, searchreq_attrlist)
183893
             log.info('%d results' % len(all_results))
183893
             assert len(all_results) == len(users_list)
183893
         log.info('If we are here, then no error has happened. We are good.')
183893
 
183893
     finally:
183893
-        log.info('Set Directory Manager bind back (test_search_dns_ip_aci)')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
         log.info('Restore ACI')
183893
-        topology_st.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_DELETE,
183893
-                                                          'aci',
183893
-                                                          None)])
183893
+        topology_st.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_DELETE, 'aci', None)])
183893
         for aci in acis_bck:
183893
-            topology_st.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_ADD,
183893
-                                                              'aci',
183893
-                                                              aci.getRawAci())])
183893
-        del_users(topology_st, users_list)
183893
+            topology_st.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_ADD, 'aci', aci.getRawAci())])
183893
+        time.sleep(1)
183893
+        del_users(users_list)
183893
 
183893
 
183893
-def test_search_multiple_paging(topology_st, test_user):
183893
+def test_search_multiple_paging(topology_st, create_user):
183893
     """Verify that after performing multiple simple paged searches
183893
     on a single connection without a complition, it wouldn't fail.
183893
 
183893
     :id: 628b29a6-2d47-4116-a88d-00b87405ef7f
183893
+    :customerscenario: True
183893
     :setup: Standalone instance, test user for binding,
183893
             varying number of users for the search base
183893
     :steps:
183893
@@ -657,15 +667,15 @@ def test_search_multiple_paging(topology_st, test_user):
183893
         4. No error happens
183893
     """
183893
 
183893
-    users_num = 100
183893
-    page_size = 30
183893
+    users_num = 20
183893
+    page_size = 5
183893
     users_list = add_users(topology_st, users_num, DEFAULT_SUFFIX)
183893
     search_flt = r'(uid=test*)'
183893
     searchreq_attrlist = ['dn', 'sn']
183893
 
183893
     try:
183893
         log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
         log.info('Create simple paged results control instance')
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
@@ -673,12 +683,9 @@ def test_search_multiple_paging(topology_st, test_user):
183893
 
183893
         for ii in range(3):
183893
             log.info('Iteration %d' % ii)
183893
-            msgid = topology_st.standalone.search_ext(DEFAULT_SUFFIX,
183893
-                                                      ldap.SCOPE_SUBTREE,
183893
-                                                      search_flt,
183893
-                                                      searchreq_attrlist,
183893
-                                                      serverctrls=controls)
183893
-            rtype, rdata, rmsgid, rctrls = topology_st.standalone.result3(msgid)
183893
+            msgid = conn.search_ext(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,
183893
+                                    search_flt, searchreq_attrlist, serverctrls=controls)
183893
+            rtype, rdata, rmsgid, rctrls = conn.result3(msgid)
183893
             pctrls = [
183893
                 c
183893
                 for c in rctrls
183893
@@ -687,24 +694,21 @@ def test_search_multiple_paging(topology_st, test_user):
183893
 
183893
             # Copy cookie from response control to request control
183893
             req_ctrl.cookie = pctrls[0].cookie
183893
-            msgid = topology_st.standalone.search_ext(DEFAULT_SUFFIX,
183893
-                                                      ldap.SCOPE_SUBTREE,
183893
-                                                      search_flt,
183893
-                                                      searchreq_attrlist,
183893
-                                                      serverctrls=controls)
183893
+            msgid = conn.search_ext(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,
183893
+                                    search_flt, searchreq_attrlist, serverctrls=controls)
183893
     finally:
183893
-        log.info('Set Directory Manager bind back (test_search_multiple_paging)')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
+        del_users(users_list)
183893
 
183893
 
183893
 @pytest.mark.parametrize("invalid_cookie", [1000, -1])
183893
-def test_search_invalid_cookie(topology_st, test_user, invalid_cookie):
183893
+def test_search_invalid_cookie(topology_st, create_user, invalid_cookie):
183893
     """Verify that using invalid cookie while performing
183893
     search with the simple paged results control throws
183893
     a TypeError exception
183893
 
183893
     :id: 107be12d-4fe4-47fe-ae86-f3e340a56f42
183893
+    :customerscenario: True
183893
+    :parametrized: yes
183893
     :setup: Standalone instance, test user for binding,
183893
             varying number of users for the search base
183893
     :steps:
183893
@@ -719,47 +723,40 @@ def test_search_invalid_cookie(topology_st, test_user, invalid_cookie):
183893
         4. It should throw a TypeError exception
183893
     """
183893
 
183893
-    users_num = 100
183893
-    page_size = 50
183893
+    users_num = 20
183893
+    page_size = 5
183893
     users_list = add_users(topology_st, users_num, DEFAULT_SUFFIX)
183893
     search_flt = r'(uid=test*)'
183893
     searchreq_attrlist = ['dn', 'sn']
183893
 
183893
     try:
183893
         log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
         log.info('Create simple paged results control instance')
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
         controls = [req_ctrl]
183893
 
183893
-        msgid = topology_st.standalone.search_ext(DEFAULT_SUFFIX,
183893
-                                                  ldap.SCOPE_SUBTREE,
183893
-                                                  search_flt,
183893
-                                                  searchreq_attrlist,
183893
-                                                  serverctrls=controls)
183893
-        rtype, rdata, rmsgid, rctrls = topology_st.standalone.result3(msgid)
183893
+        msgid = conn.search_ext(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,
183893
+                                search_flt, searchreq_attrlist, serverctrls=controls)
183893
+        rtype, rdata, rmsgid, rctrls = conn.result3(msgid)
183893
 
183893
         log.info('Put an invalid cookie (%d) to the control. TypeError is expected' %
183893
                  invalid_cookie)
183893
         req_ctrl.cookie = invalid_cookie
183893
         with pytest.raises(TypeError):
183893
-            msgid = topology_st.standalone.search_ext(DEFAULT_SUFFIX,
183893
-                                                      ldap.SCOPE_SUBTREE,
183893
-                                                      search_flt,
183893
-                                                      searchreq_attrlist,
183893
-                                                      serverctrls=controls)
183893
+            msgid = conn.search_ext(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,
183893
+                                    search_flt, searchreq_attrlist, serverctrls=controls)
183893
     finally:
183893
-        log.info('Set Directory Manager bind back (test_search_invalid_cookie)')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
+        del_users(users_list)
183893
 
183893
 
183893
-def test_search_abandon_with_zero_size(topology_st, test_user):
183893
+def test_search_abandon_with_zero_size(topology_st, create_user):
183893
     """Verify that search with simple paged results control
183893
     can be abandon using page_size = 0
183893
 
183893
     :id: d2fd9a10-84e1-4b69-a8a7-36ca1427c171
183893
+    :customerscenario: True
183893
     :setup: Standalone instance, test user for binding,
183893
             varying number of users for the search base
183893
     :steps:
183893
@@ -779,18 +776,15 @@ def test_search_abandon_with_zero_size(topology_st, test_user):
183893
 
183893
     try:
183893
         log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
         log.info('Create simple paged results control instance')
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
         controls = [req_ctrl]
183893
 
183893
-        msgid = topology_st.standalone.search_ext(DEFAULT_SUFFIX,
183893
-                                                  ldap.SCOPE_SUBTREE,
183893
-                                                  search_flt,
183893
-                                                  searchreq_attrlist,
183893
-                                                  serverctrls=controls)
183893
-        rtype, rdata, rmsgid, rctrls = topology_st.standalone.result3(msgid)
183893
+        msgid = conn.search_ext(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,
183893
+                                search_flt, searchreq_attrlist, serverctrls=controls)
183893
+        rtype, rdata, rmsgid, rctrls = conn.result3(msgid)
183893
         pctrls = [
183893
             c
183893
             for c in rctrls
183893
@@ -798,17 +792,16 @@ def test_search_abandon_with_zero_size(topology_st, test_user):
183893
             ]
183893
         assert not pctrls[0].cookie
183893
     finally:
183893
-        log.info('Set Directory Manager bind back (test_search_abandon_with_zero_size)')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
+        del_users(users_list)
183893
 
183893
 
183893
-def test_search_pagedsizelimit_success(topology_st, test_user):
183893
+def test_search_pagedsizelimit_success(topology_st, create_user):
183893
     """Verify that search with a simple paged results control
183893
     returns all entries it should without errors while
183893
     valid value set to nsslapd-pagedsizelimit.
183893
 
183893
     :id: 88193f10-f6f0-42f5-ae9c-ff34b8f9ee8c
183893
+    :customerscenario: True
183893
     :setup: Standalone instance, test user for binding,
183893
             10 users for the search base
183893
     :steps:
183893
@@ -826,42 +819,39 @@ def test_search_pagedsizelimit_success(topology_st, test_user):
183893
     page_size = 10
183893
     attr_name = 'nsslapd-pagedsizelimit'
183893
     attr_value = '20'
183893
-    attr_value_bck = change_conf_attr(topology_st, DN_CONFIG,
183893
-                                      attr_name, attr_value)
183893
+    attr_value_bck = change_conf_attr(topology_st, DN_CONFIG, attr_name, attr_value)
183893
     users_list = add_users(topology_st, users_num, DEFAULT_SUFFIX)
183893
     search_flt = r'(uid=test*)'
183893
     searchreq_attrlist = ['dn', 'sn']
183893
 
183893
     try:
183893
         log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
         controls = [req_ctrl]
183893
 
183893
-        all_results = paged_search(topology_st, DEFAULT_SUFFIX, controls,
183893
-                                   search_flt, searchreq_attrlist)
183893
+        all_results = paged_search(conn, DEFAULT_SUFFIX, controls, search_flt, searchreq_attrlist)
183893
 
183893
         log.info('%d results' % len(all_results))
183893
         assert len(all_results) == len(users_list)
183893
 
183893
     finally:
183893
-        log.info('Set Directory Manager bind back (test_search_pagedsizelimit_success)')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
-        change_conf_attr(topology_st, DN_CONFIG,
183893
-                         'nsslapd-pagedsizelimit', attr_value_bck)
183893
+        del_users(users_list)
183893
+        change_conf_attr(topology_st, DN_CONFIG, 'nsslapd-pagedsizelimit', attr_value_bck)
183893
 
183893
 
183893
 @pytest.mark.parametrize('conf_attr,user_attr,expected_rs',
183893
                          (('5', '15', 'PASS'), ('15', '5', ldap.SIZELIMIT_EXCEEDED)))
183893
-def test_search_nspagedsizelimit(topology_st, test_user,
183893
+def test_search_nspagedsizelimit(topology_st, create_user,
183893
                                  conf_attr, user_attr, expected_rs):
183893
     """Verify that nsPagedSizeLimit attribute overrides
183893
     nsslapd-pagedsizelimit while performing search with
183893
     the simple paged results control.
183893
 
183893
     :id: b08c6ad2-ba28-447a-9f04-5377c3661d0d
183893
+    :customerscenario: True
183893
+    :parametrized: yes
183893
     :setup: Standalone instance, test user for binding,
183893
             10 users for the search base
183893
     :steps:
183893
@@ -895,14 +885,12 @@ def test_search_nspagedsizelimit(topology_st, test_user,
183893
     users_list = add_users(topology_st, users_num, DEFAULT_SUFFIX)
183893
     search_flt = r'(uid=test*)'
183893
     searchreq_attrlist = ['dn', 'sn']
183893
-    conf_attr_bck = change_conf_attr(topology_st, DN_CONFIG,
183893
-                                     'nsslapd-pagedsizelimit', conf_attr)
183893
-    user_attr_bck = change_conf_attr(topology_st, TEST_USER_DN,
183893
-                                     'nsPagedSizeLimit', user_attr)
183893
+    conf_attr_bck = change_conf_attr(topology_st, DN_CONFIG, 'nsslapd-pagedsizelimit', conf_attr)
183893
+    user_attr_bck = change_conf_attr(topology_st, create_user.dn, 'nsPagedSizeLimit', user_attr)
183893
 
183893
     try:
183893
         log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
         controls = [req_ctrl]
183893
@@ -910,34 +898,30 @@ def test_search_nspagedsizelimit(topology_st, test_user,
183893
         if expected_rs == ldap.SIZELIMIT_EXCEEDED:
183893
             log.info('Expect to fail with SIZELIMIT_EXCEEDED')
183893
             with pytest.raises(expected_rs):
183893
-                all_results = paged_search(topology_st, DEFAULT_SUFFIX, controls,
183893
-                                           search_flt, searchreq_attrlist)
183893
+                all_results = paged_search(conn, DEFAULT_SUFFIX, controls, search_flt, searchreq_attrlist)
183893
         elif expected_rs == 'PASS':
183893
             log.info('Expect to pass')
183893
-            all_results = paged_search(topology_st, DEFAULT_SUFFIX, controls,
183893
-                                       search_flt, searchreq_attrlist)
183893
+            all_results = paged_search(conn, DEFAULT_SUFFIX, controls, search_flt, searchreq_attrlist)
183893
             log.info('%d results' % len(all_results))
183893
             assert len(all_results) == len(users_list)
183893
 
183893
     finally:
183893
-        log.info('Set Directory Manager bind back (test_search_nspagedsizelimit)')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
-        change_conf_attr(topology_st, DN_CONFIG,
183893
-                         'nsslapd-pagedsizelimit', conf_attr_bck)
183893
-        change_conf_attr(topology_st, TEST_USER_DN,
183893
-                         'nsPagedSizeLimit', user_attr_bck)
183893
+        del_users(users_list)
183893
+        change_conf_attr(topology_st, DN_CONFIG, 'nsslapd-pagedsizelimit', conf_attr_bck)
183893
+        change_conf_attr(topology_st, create_user.dn, 'nsPagedSizeLimit', user_attr_bck)
183893
 
183893
 
183893
 @pytest.mark.parametrize('conf_attr_values,expected_rs',
183893
                          ((('5000', '100', '100'), ldap.ADMINLIMIT_EXCEEDED),
183893
                           (('5000', '120', '122'), 'PASS')))
183893
-def test_search_paged_limits(topology_st, test_user, conf_attr_values, expected_rs):
183893
+def test_search_paged_limits(topology_st, create_user, conf_attr_values, expected_rs):
183893
     """Verify that nsslapd-idlistscanlimit and
183893
     nsslapd-lookthroughlimit can limit the administrator
183893
     search abilities.
183893
 
183893
     :id: e0f8b916-7276-4bd3-9e73-8696a4468811
183893
+    :customerscenario: True
183893
+    :parametrized: yes
183893
     :setup: Standalone instance, test user for binding,
183893
             10 users for the search base
183893
     :steps:
183893
@@ -972,18 +956,14 @@ def test_search_paged_limits(topology_st, test_user, conf_attr_values, expected_
183893
     users_list = add_users(topology_st, users_num, DEFAULT_SUFFIX)
183893
     search_flt = r'(uid=test*)'
183893
     searchreq_attrlist = ['dn', 'sn']
183893
-    size_attr_bck = change_conf_attr(topology_st, DN_CONFIG,
183893
-                                     'nsslapd-sizelimit', conf_attr_values[0])
183893
-    pagedsize_attr_bck = change_conf_attr(topology_st, DN_CONFIG,
183893
-                                          'nsslapd-pagedsizelimit', conf_attr_values[0])
183893
-    idlistscan_attr_bck = change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM,
183893
-                                           'nsslapd-idlistscanlimit', conf_attr_values[1])
183893
-    lookthrough_attr_bck = change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM,
183893
-                                            'nsslapd-lookthroughlimit', conf_attr_values[2])
183893
+    size_attr_bck = change_conf_attr(topology_st, DN_CONFIG, 'nsslapd-sizelimit', conf_attr_values[0])
183893
+    pagedsize_attr_bck = change_conf_attr(topology_st, DN_CONFIG, 'nsslapd-pagedsizelimit', conf_attr_values[0])
183893
+    idlistscan_attr_bck = change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM, 'nsslapd-idlistscanlimit', conf_attr_values[1])
183893
+    lookthrough_attr_bck = change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM, 'nsslapd-lookthroughlimit', conf_attr_values[2])
183893
 
183893
     try:
183893
         log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
         controls = [req_ctrl]
183893
@@ -991,37 +971,31 @@ def test_search_paged_limits(topology_st, test_user, conf_attr_values, expected_
183893
         if expected_rs == ldap.ADMINLIMIT_EXCEEDED:
183893
             log.info('Expect to fail with ADMINLIMIT_EXCEEDED')
183893
             with pytest.raises(expected_rs):
183893
-                all_results = paged_search(topology_st, DEFAULT_SUFFIX, controls,
183893
-                                           search_flt, searchreq_attrlist)
183893
+                all_results = paged_search(conn, DEFAULT_SUFFIX, controls, search_flt, searchreq_attrlist)
183893
         elif expected_rs == 'PASS':
183893
             log.info('Expect to pass')
183893
-            all_results = paged_search(topology_st, DEFAULT_SUFFIX, controls,
183893
-                                       search_flt, searchreq_attrlist)
183893
+            all_results = paged_search(conn, DEFAULT_SUFFIX, controls, search_flt, searchreq_attrlist)
183893
             log.info('%d results' % len(all_results))
183893
             assert len(all_results) == len(users_list)
183893
     finally:
183893
-        log.info('Set Directory Manager bind back (test_search_paged_limits)')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
-        change_conf_attr(topology_st, DN_CONFIG,
183893
-                         'nsslapd-sizelimit', size_attr_bck)
183893
-        change_conf_attr(topology_st, DN_CONFIG,
183893
-                         'nsslapd-pagedsizelimit', pagedsize_attr_bck)
183893
-        change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM,
183893
-                         'nsslapd-lookthroughlimit', lookthrough_attr_bck)
183893
-        change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM,
183893
-                         'nsslapd-idlistscanlimit', idlistscan_attr_bck)
183893
+        del_users(users_list)
183893
+        change_conf_attr(topology_st, DN_CONFIG, 'nsslapd-sizelimit', size_attr_bck)
183893
+        change_conf_attr(topology_st, DN_CONFIG, 'nsslapd-pagedsizelimit', pagedsize_attr_bck)
183893
+        change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM, 'nsslapd-lookthroughlimit', lookthrough_attr_bck)
183893
+        change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM, 'nsslapd-idlistscanlimit', idlistscan_attr_bck)
183893
 
183893
 
183893
 @pytest.mark.parametrize('conf_attr_values,expected_rs',
183893
                          ((('1000', '100', '100'), ldap.ADMINLIMIT_EXCEEDED),
183893
                           (('1000', '120', '122'), 'PASS')))
183893
-def test_search_paged_user_limits(topology_st, test_user, conf_attr_values, expected_rs):
183893
+def test_search_paged_user_limits(topology_st, create_user, conf_attr_values, expected_rs):
183893
     """Verify that nsPagedIDListScanLimit and nsPagedLookthroughLimit
183893
     override nsslapd-idlistscanlimit and nsslapd-lookthroughlimit
183893
     while performing search with the simple paged results control.
183893
 
183893
     :id: 69e393e9-1ab8-4f4e-b4a1-06ca63dc7b1b
183893
+    :customerscenario: True
183893
+    :parametrized: yes
183893
     :setup: Standalone instance, test user for binding,
183893
             10 users for the search base
183893
     :steps:
183893
@@ -1057,18 +1031,14 @@ def test_search_paged_user_limits(topology_st, test_user, conf_attr_values, expe
183893
     users_list = add_users(topology_st, users_num, DEFAULT_SUFFIX)
183893
     search_flt = r'(uid=test*)'
183893
     searchreq_attrlist = ['dn', 'sn']
183893
-    lookthrough_attr_bck = change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM,
183893
-                                            'nsslapd-lookthroughlimit', conf_attr_values[0])
183893
-    idlistscan_attr_bck = change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM,
183893
-                                           'nsslapd-idlistscanlimit', conf_attr_values[0])
183893
-    user_idlistscan_attr_bck = change_conf_attr(topology_st, TEST_USER_DN,
183893
-                                                'nsPagedIDListScanLimit', conf_attr_values[1])
183893
-    user_lookthrough_attr_bck = change_conf_attr(topology_st, TEST_USER_DN,
183893
-                                                 'nsPagedLookthroughLimit', conf_attr_values[2])
183893
+    lookthrough_attr_bck = change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM, 'nsslapd-lookthroughlimit', conf_attr_values[0])
183893
+    idlistscan_attr_bck = change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM, 'nsslapd-idlistscanlimit', conf_attr_values[0])
183893
+    user_idlistscan_attr_bck = change_conf_attr(topology_st, create_user.dn, 'nsPagedIDListScanLimit', conf_attr_values[1])
183893
+    user_lookthrough_attr_bck = change_conf_attr(topology_st, create_user.dn, 'nsPagedLookthroughLimit', conf_attr_values[2])
183893
 
183893
     try:
183893
         log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
         controls = [req_ctrl]
183893
@@ -1076,34 +1046,27 @@ def test_search_paged_user_limits(topology_st, test_user, conf_attr_values, expe
183893
         if expected_rs == ldap.ADMINLIMIT_EXCEEDED:
183893
             log.info('Expect to fail with ADMINLIMIT_EXCEEDED')
183893
             with pytest.raises(expected_rs):
183893
-                all_results = paged_search(topology_st, DEFAULT_SUFFIX, controls,
183893
-                                           search_flt, searchreq_attrlist)
183893
+                all_results = paged_search(conn, DEFAULT_SUFFIX, controls, search_flt, searchreq_attrlist)
183893
         elif expected_rs == 'PASS':
183893
             log.info('Expect to pass')
183893
-            all_results = paged_search(topology_st, DEFAULT_SUFFIX, controls,
183893
-                                       search_flt, searchreq_attrlist)
183893
+            all_results = paged_search(conn, DEFAULT_SUFFIX, controls, search_flt, searchreq_attrlist)
183893
             log.info('%d results' % len(all_results))
183893
             assert len(all_results) == len(users_list)
183893
     finally:
183893
-        log.info('Set Directory Manager bind back (test_search_paged_user_limits)')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
-        change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM,
183893
-                         'nsslapd-lookthroughlimit', lookthrough_attr_bck)
183893
-        change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM,
183893
-                         'nsslapd-idlistscanlimit', idlistscan_attr_bck)
183893
-        change_conf_attr(topology_st, TEST_USER_DN,
183893
-                         'nsPagedIDListScanLimit', user_idlistscan_attr_bck)
183893
-        change_conf_attr(topology_st, TEST_USER_DN,
183893
-                         'nsPagedLookthroughLimit', user_lookthrough_attr_bck)
183893
-
183893
-
183893
-def test_ger_basic(topology_st, test_user):
183893
+        del_users(users_list)
183893
+        change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM, 'nsslapd-lookthroughlimit', lookthrough_attr_bck)
183893
+        change_conf_attr(topology_st, 'cn=config,%s' % DN_LDBM, 'nsslapd-idlistscanlimit', idlistscan_attr_bck)
183893
+        change_conf_attr(topology_st, create_user.dn, 'nsPagedIDListScanLimit', user_idlistscan_attr_bck)
183893
+        change_conf_attr(topology_st, create_user.dn, 'nsPagedLookthroughLimit', user_lookthrough_attr_bck)
183893
+
183893
+
183893
+def test_ger_basic(topology_st, create_user):
183893
     """Verify that search with a simple paged results control
183893
     and get effective rights control returns all entries
183893
     it should without errors.
183893
 
183893
     :id: 7b0bdfc7-a2f2-4c1a-bcab-f1eb8b330d45
183893
+    :customerscenario: True
183893
     :setup: Standalone instance, test user for binding,
183893
             varying number of users for the search base
183893
     :steps:
183893
@@ -1120,13 +1083,10 @@ def test_ger_basic(topology_st, test_user):
183893
     page_size = 4
183893
 
183893
     try:
183893
-        log.info('Set bind to directory manager')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-
183893
         spr_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
-        ger_ctrl = GetEffectiveRightsControl(True, "dn: " + DN_DM)
183893
+        ger_ctrl = GetEffectiveRightsControl(True, ensure_bytes("dn: " + DN_DM))
183893
 
183893
-        all_results = paged_search(topology_st, DEFAULT_SUFFIX, [spr_ctrl, ger_ctrl],
183893
+        all_results = paged_search(topology_st.standalone, DEFAULT_SUFFIX, [spr_ctrl, ger_ctrl],
183893
                                    search_flt, searchreq_attrlist)
183893
 
183893
         log.info('{} results'.format(len(all_results)))
183893
@@ -1135,14 +1095,15 @@ def test_ger_basic(topology_st, test_user):
183893
         assert all(attrs['attributeLevelRights'][0] for dn, attrs in all_results)
183893
     finally:
183893
         log.info('Remove added users')
183893
-        del_users(topology_st, users_list)
183893
+        del_users(users_list)
183893
 
183893
 
183893
-def test_multi_suffix_search(topology_st, test_user, new_suffixes):
183893
+def test_multi_suffix_search(topology_st, create_user, new_suffixes):
183893
     """Verify that page result search returns empty cookie
183893
     if there is no returned entry.
183893
 
183893
     :id: 9712345b-9e38-4df6-8794-05f12c457d39
183893
+    :customerscenario: True
183893
     :setup: Standalone instance, test user for binding,
183893
             two suffixes with backends, one is inserted into another,
183893
             10 users for the search base within each suffix
183893
@@ -1168,17 +1129,13 @@ def test_multi_suffix_search(topology_st, test_user, new_suffixes):
183893
     log.info('Clear the access log')
183893
     topology_st.standalone.deleteAccessLogs()
183893
 
183893
-    users_list_1 = add_users(topology_st, users_num / 2, NEW_SUFFIX_1)
183893
-    users_list_2 = add_users(topology_st, users_num / 2, NEW_SUFFIX_2)
183893
+    users_list_1 = add_users(topology_st, 10, NEW_SUFFIX_1)
183893
+    users_list_2 = add_users(topology_st, 10, NEW_SUFFIX_2)
183893
 
183893
     try:
183893
-        log.info('Set DM bind')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
 
183893
-        all_results = paged_search(topology_st, NEW_SUFFIX_1, [req_ctrl],
183893
-                                   search_flt, searchreq_attrlist)
183893
+        all_results = paged_search(topology_st.standalone, NEW_SUFFIX_1, [req_ctrl], search_flt, searchreq_attrlist)
183893
 
183893
         log.info('{} results'.format(len(all_results)))
183893
         assert len(all_results) == users_num
183893
@@ -1195,15 +1152,17 @@ def test_multi_suffix_search(topology_st, test_user, new_suffixes):
183893
         assert pr_cookie_list[-1] == -1
183893
     finally:
183893
         log.info('Remove added users')
183893
-        del_users(topology_st, users_list_1)
183893
-        del_users(topology_st, users_list_2)
183893
+        del_users(users_list_1)
183893
+        del_users(users_list_2)
183893
 
183893
 
183893
 @pytest.mark.parametrize('conf_attr_value', (None, '-1', '1000'))
183893
-def test_maxsimplepaged_per_conn_success(topology_st, test_user, conf_attr_value):
183893
+def test_maxsimplepaged_per_conn_success(topology_st, create_user, conf_attr_value):
183893
     """Verify that nsslapd-maxsimplepaged-per-conn acts according design
183893
 
183893
     :id: 192e2f25-04ee-4ff9-9340-d875dcbe8011
183893
+    :customerscenario: True
183893
+    :parametrized: yes
183893
     :setup: Standalone instance, test user for binding,
183893
             20 users for the search base
183893
     :steps:
183893
@@ -1223,35 +1182,32 @@ def test_maxsimplepaged_per_conn_success(topology_st, test_user, conf_attr_value
183893
     searchreq_attrlist = ['dn', 'sn']
183893
     page_size = 4
183893
     if conf_attr_value:
183893
-        max_per_con_bck = change_conf_attr(topology_st, DN_CONFIG,
183893
-                                           'nsslapd-maxsimplepaged-per-conn',
183893
-                                           conf_attr_value)
183893
+        max_per_con_bck = change_conf_attr(topology_st, DN_CONFIG, 'nsslapd-maxsimplepaged-per-conn', conf_attr_value)
183893
 
183893
     try:
183893
         log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
 
183893
-        all_results = paged_search(topology_st, DEFAULT_SUFFIX, [req_ctrl],
183893
-                                   search_flt, searchreq_attrlist)
183893
+        all_results = paged_search(conn, DEFAULT_SUFFIX, [req_ctrl], search_flt, searchreq_attrlist)
183893
 
183893
         log.info('{} results'.format(len(all_results)))
183893
         assert len(all_results) == len(users_list)
183893
     finally:
183893
         log.info('Remove added users')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
+        del_users(users_list)
183893
         if conf_attr_value:
183893
-            change_conf_attr(topology_st, DN_CONFIG,
183893
-                             'nsslapd-maxsimplepaged-per-conn', max_per_con_bck)
183893
+            change_conf_attr(topology_st, DN_CONFIG, 'nsslapd-maxsimplepaged-per-conn', max_per_con_bck)
183893
 
183893
 
183893
 @pytest.mark.parametrize('conf_attr_value', ('0', '1'))
183893
-def test_maxsimplepaged_per_conn_failure(topology_st, test_user, conf_attr_value):
183893
+def test_maxsimplepaged_per_conn_failure(topology_st, create_user, conf_attr_value):
183893
     """Verify that nsslapd-maxsimplepaged-per-conn acts according design
183893
 
183893
     :id: eb609e63-2829-4331-8439-a35f99694efa
183893
+    :customerscenario: True
183893
+    :parametrized: yes
183893
     :setup: Standalone instance, test user for binding,
183893
             20 users for the search base
183893
     :steps:
183893
@@ -1272,40 +1228,62 @@ def test_maxsimplepaged_per_conn_failure(topology_st, test_user, conf_attr_value
183893
     search_flt = r'(uid=test*)'
183893
     searchreq_attrlist = ['dn', 'sn']
183893
     page_size = 4
183893
-    max_per_con_bck = change_conf_attr(topology_st, DN_CONFIG,
183893
-                                       'nsslapd-maxsimplepaged-per-conn',
183893
-                                       conf_attr_value)
183893
+    max_per_con_bck = change_conf_attr(topology_st, DN_CONFIG, 'nsslapd-maxsimplepaged-per-conn', conf_attr_value)
183893
 
183893
     try:
183893
         log.info('Set user bind')
183893
-        topology_st.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
183893
+        conn = create_user.bind(TEST_USER_PWD)
183893
 
183893
         log.info('Create simple paged results control instance')
183893
         req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
 
183893
         with pytest.raises(ldap.UNWILLING_TO_PERFORM):
183893
-            msgid = topology_st.standalone.search_ext(DEFAULT_SUFFIX,
183893
-                                                      ldap.SCOPE_SUBTREE,
183893
-                                                      search_flt,
183893
-                                                      searchreq_attrlist,
183893
-                                                      serverctrls=[req_ctrl])
183893
-            rtype, rdata, rmsgid, rctrls = topology_st.standalone.result3(msgid)
183893
+            msgid = conn.search_ext(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,
183893
+                                    search_flt, searchreq_attrlist, serverctrls=[req_ctrl])
183893
+            rtype, rdata, rmsgid, rctrls = conn.result3(msgid)
183893
 
183893
             # If nsslapd-maxsimplepaged-per-conn = 1,
183893
             # it should pass this point, but failed on the next search
183893
             assert conf_attr_value == '1'
183893
-            msgid = topology_st.standalone.search_ext(DEFAULT_SUFFIX,
183893
-                                                      ldap.SCOPE_SUBTREE,
183893
-                                                      search_flt,
183893
-                                                      searchreq_attrlist,
183893
-                                                      serverctrls=[req_ctrl])
183893
-            rtype, rdata, rmsgid, rctrls = topology_st.standalone.result3(msgid)
183893
+            msgid = conn.search_ext(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,
183893
+                                    search_flt, searchreq_attrlist, serverctrls=[req_ctrl])
183893
+            rtype, rdata, rmsgid, rctrls = conn.result3(msgid)
183893
     finally:
183893
         log.info('Remove added users')
183893
-        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
183893
-        del_users(topology_st, users_list)
183893
-        change_conf_attr(topology_st, DN_CONFIG,
183893
-                         'nsslapd-maxsimplepaged-per-conn', max_per_con_bck)
183893
+        del_users(users_list)
183893
+        change_conf_attr(topology_st, DN_CONFIG, 'nsslapd-maxsimplepaged-per-conn', max_per_con_bck)
183893
+
183893
+
183893
+def test_search_stress_abandon(create_40k_users, create_user):
183893
+    """Verify that search with a simple paged results control
183893
+    returns all entries it should without errors.
183893
+
183893
+    :id: e154b24a-83d6-11ee-90d1-482ae39447e5
183893
+    :customerscenario: True
183893
+    :feature: Simple paged results
183893
+    :setup: Standalone instance, test user for binding,
183893
+            40K  users in a second backend
183893
+    :steps:
183893
+        1. Bind as test user
183893
+        2. Loops a number of times doing:
183893
+                 - search through added users with a simple paged control
183893
+                 - randomly abandoning the search after a few ms.
183893
+    :expectedresults:
183893
+        1. Bind should be successful
183893
+        2. The loop should complete successfully.
183893
+    """
183893
+
183893
+    abandon_rate = 10
183893
+    page_size = 500
183893
+    nbloops = 1000
183893
+    search_flt = r'(uid=*)'
183893
+    searchreq_attrlist = ['dn', 'sn']
183893
+    log.info('Set user bind %s ' % create_user)
183893
+    conn = create_user.bind(TEST_USER_PWD)
183893
+    for idx in range(nbloops):
183893
+        req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
183893
+        # If the issue #5984 is not fixed the server crashs and the paged search fails with ldap.SERVER_DOWN exception
183893
+        paged_search(conn, create_40k_users.suffix, [req_ctrl], search_flt, searchreq_attrlist, abandon_rate=abandon_rate)
183893
 
183893
 
183893
 if __name__ == '__main__':
183893
diff --git a/ldap/servers/slapd/abandon.c b/ldap/servers/slapd/abandon.c
183893
index 3f7bef018..0d16b60e6 100644
183893
--- a/ldap/servers/slapd/abandon.c
183893
+++ b/ldap/servers/slapd/abandon.c
183893
@@ -38,6 +38,12 @@ do_abandon(Slapi_PBlock *pb)
183893
     Connection *pb_conn = NULL;
183893
     Operation *pb_op = NULL;
183893
     Operation *o;
183893
+    /* Keep a copy of some data because o may vanish once conn is unlocked */
183893
+    struct {
183893
+        struct timespec hr_time_end;
183893
+        int nentries;
183893
+        int opid;
183893
+    } o_copy;
183893
 
183893
     slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
183893
     slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
183893
@@ -90,8 +96,12 @@ do_abandon(Slapi_PBlock *pb)
183893
 
183893
     PR_EnterMonitor(pb_conn->c_mutex);
183893
     for (o = pb_conn->c_ops; o != NULL; o = o->o_next) {
183893
-        if (o->o_msgid == id && o != pb_op)
183893
+        if (o->o_msgid == id && o != pb_op) {
183893
+            slapi_operation_time_elapsed(o, &o_copy.hr_time_end);
183893
+            o_copy.nentries = o->o_results.r.r_search.nentries;
183893
+            o_copy.opid = o->o_opid;
183893
             break;
183893
+        }
183893
     }
183893
 
183893
     if (o != NULL) {
183893
@@ -130,7 +140,8 @@ do_abandon(Slapi_PBlock *pb)
183893
         slapi_log_err(SLAPI_LOG_TRACE, "do_abandon", "op not found\n");
183893
     }
183893
 
183893
-    if (0 == pagedresults_free_one_msgid_nolock(pb_conn, id)) {
183893
+    PR_ExitMonitor(pb_conn->c_mutex);
183893
+    if (0 == pagedresults_free_one_msgid(pb_conn, id, pageresult_lock_get_addr(pb_conn))) {
183893
         slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64
183893
                                            " op=%d ABANDON targetop=Simple Paged Results msgid=%d\n",
183893
                          pb_conn->c_connid, pb_op->o_opid, id);
183893
@@ -143,15 +154,11 @@ do_abandon(Slapi_PBlock *pb)
183893
                                            " targetop=SUPPRESSED-BY-PLUGIN msgid=%d\n",
183893
                          pb_conn->c_connid, pb_op->o_opid, id);
183893
     } else {
183893
-        struct timespec o_hr_time_end;
183893
-        slapi_operation_time_elapsed(o, &o_hr_time_end);
183893
         slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d ABANDON"
183893
                                            " targetop=%d msgid=%d nentries=%d etime=%" PRId64 ".%010" PRId64 "\n",
183893
-                         pb_conn->c_connid, pb_op->o_opid, o->o_opid, id,
183893
-                         o->o_results.r.r_search.nentries, (int64_t)o_hr_time_end.tv_sec, (int64_t)o_hr_time_end.tv_nsec);
183893
+                         pb_conn->c_connid, pb_op->o_opid, o_copy.opid, id,
183893
+                         o_copy.nentries, (int64_t)o_copy.hr_time_end.tv_sec, (int64_t)o_copy.hr_time_end.tv_nsec);
183893
     }
183893
-
183893
-    PR_ExitMonitor(pb_conn->c_mutex);
183893
     /*
183893
      * Wake up the persistent searches, so they
183893
      * can notice if they've been abandoned.
183893
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
183893
index ec316dfb9..80c670d7b 100644
183893
--- a/ldap/servers/slapd/opshared.c
183893
+++ b/ldap/servers/slapd/opshared.c
183893
@@ -889,9 +889,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
183893
                     next_be = NULL; /* to break the loop */
183893
                     if (operation->o_status & SLAPI_OP_STATUS_ABANDONED) {
183893
                         /* It turned out this search was abandoned. */
183893
-                        pthread_mutex_lock(pagedresults_mutex);
183893
-                        pagedresults_free_one_msgid_nolock(pb_conn, operation->o_msgid);
183893
-                        pthread_mutex_unlock(pagedresults_mutex);
183893
+                        pagedresults_free_one_msgid(pb_conn, operation->o_msgid, pagedresults_mutex);
183893
                         /* paged-results-request was abandoned; making an empty cookie. */
183893
                         pagedresults_set_response_control(pb, 0, estimate, -1, pr_idx);
183893
                         send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL);
183893
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
183893
index 8c043f6af..dc9db2c60 100644
183893
--- a/ldap/servers/slapd/pagedresults.c
183893
+++ b/ldap/servers/slapd/pagedresults.c
183893
@@ -34,6 +34,10 @@ pageresult_lock_cleanup()
183893
     slapi_ch_free((void**)&lock_hash);
183893
 }
183893
 
183893
+/* Beware to the lock order with c_mutex:
183893
+ * c_mutex is sometime locked while holding pageresult_lock
183893
+ * ==> Do not lock pageresult_lock when holing c_mutex
183893
+ */
183893
 pthread_mutex_t *
183893
 pageresult_lock_get_addr(Connection *conn)
183893
 {
183893
@@ -350,7 +354,7 @@ pagedresults_free_one(Connection *conn, Operation *op, int index)
183893
  * Used for abandoning - pageresult_lock_get_addr(conn) is already locked in do_abandone.
183893
  */
183893
 int
183893
-pagedresults_free_one_msgid_nolock(Connection *conn, ber_int_t msgid)
183893
+pagedresults_free_one_msgid(Connection *conn, ber_int_t msgid, pthread_mutex_t *mutex)
183893
 {
183893
     int rc = -1;
183893
     int i;
183893
@@ -361,6 +365,7 @@ pagedresults_free_one_msgid_nolock(Connection *conn, ber_int_t msgid)
183893
         } else {
183893
             slapi_log_err(SLAPI_LOG_TRACE,
183893
                           "pagedresults_free_one_msgid_nolock", "=> msgid=%d\n", msgid);
183893
+            pthread_mutex_lock(mutex);
183893
             for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
183893
                 if (conn->c_pagedresults.prl_list[i].pr_msgid == msgid) {
183893
                     PagedResults *prp = conn->c_pagedresults.prl_list + i;
183893
@@ -375,6 +380,7 @@ pagedresults_free_one_msgid_nolock(Connection *conn, ber_int_t msgid)
183893
                     break;
183893
                 }
183893
             }
183893
+            pthread_mutex_unlock(mutex);
183893
             slapi_log_err(SLAPI_LOG_TRACE,
183893
                           "pagedresults_free_one_msgid_nolock", "<= %d\n", rc);
183893
         }
183893
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
183893
index b8f736107..a02605774 100644
183893
--- a/ldap/servers/slapd/proto-slap.h
183893
+++ b/ldap/servers/slapd/proto-slap.h
183893
@@ -1525,7 +1525,7 @@ int pagedresults_is_timedout_nolock(Connection *conn);
183893
 int pagedresults_reset_timedout_nolock(Connection *conn);
183893
 int pagedresults_in_use_nolock(Connection *conn);
183893
 int pagedresults_free_one(Connection *conn, Operation *op, int index);
183893
-int pagedresults_free_one_msgid_nolock(Connection *conn, ber_int_t msgid);
183893
+int pagedresults_free_one_msgid(Connection *conn, ber_int_t msgid, pthread_mutex_t *mutex);
183893
 int op_is_pagedresults(Operation *op);
183893
 int pagedresults_cleanup_all(Connection *conn, int needlock);
183893
 void op_set_pagedresults(Operation *op);
183893
-- 
183893
2.41.0
183893