d4e26e
From 5dafe01e0f52abb3679d1a53a229378331a73ca6 Mon Sep 17 00:00:00 2001
d4e26e
From: Mark Reynolds <mreynolds@redhat.com>
d4e26e
Date: Tue, 9 Feb 2021 14:02:59 -0500
d4e26e
Subject: [PATCH] Issue 4609 - CVE - info disclosure when authenticating
d4e26e
d4e26e
Description:  If you bind as a user that does not exist.  Error 49 is returned
d4e26e
              instead of error 32.  As error 32 discloses that the entry does
d4e26e
              not exist.  When you bind as an entry that does not have userpassword
d4e26e
              set then error 48 (inappropriate auth) is returned, but this
d4e26e
              discloses that the entry does indeed exist.  Instead we should
d4e26e
              always return error 49, even if the password is not set in the
d4e26e
              entry.  This way we do not disclose to an attacker if the Bind
d4e26e
              DN exists or not.
d4e26e
d4e26e
Relates: https://github.com/389ds/389-ds-base/issues/4609
d4e26e
d4e26e
Reviewed by: tbordaz(Thanks!)
d4e26e
---
d4e26e
 dirsrvtests/tests/suites/basic/basic_test.py | 1174 ------------------
d4e26e
 ldap/servers/slapd/back-ldbm/ldbm_bind.c     |    4 +-
d4e26e
 ldap/servers/slapd/dse.c                     |    7 +-
d4e26e
 3 files changed, 7 insertions(+), 1178 deletions(-)
d4e26e
 delete mode 100644 dirsrvtests/tests/suites/basic/basic_test.py
d4e26e
d4e26e
diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py
d4e26e
deleted file mode 100644
d4e26e
index cea4f6bfe..000000000
d4e26e
--- a/dirsrvtests/tests/suites/basic/basic_test.py
d4e26e
+++ /dev/null
d4e26e
@@ -1,1174 +0,0 @@
d4e26e
-# --- BEGIN COPYRIGHT BLOCK ---
d4e26e
-# Copyright (C) 2016 Red Hat, Inc.
d4e26e
-# All rights reserved.
d4e26e
-#
d4e26e
-# License: GPL (version 3 or any later version).
d4e26e
-# See LICENSE for details.
d4e26e
-# --- END COPYRIGHT BLOCK ---
d4e26e
-#
d4e26e
-
d4e26e
-"""
d4e26e
-   :Requirement: Basic Directory Server Operations
d4e26e
-"""
d4e26e
-
d4e26e
-from subprocess import check_output, Popen
d4e26e
-
d4e26e
-import pytest
d4e26e
-from lib389.tasks import *
d4e26e
-from lib389.utils import *
d4e26e
-from lib389.topologies import topology_st
d4e26e
-from lib389.dbgen import dbgen
d4e26e
-
d4e26e
-from lib389._constants import DN_DM, PASSWORD, PW_DM
d4e26e
-from lib389.topologies import topology_st
d4e26e
-
d4e26e
-log = logging.getLogger(__name__)
d4e26e
-
d4e26e
-# Globals
d4e26e
-USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX
d4e26e
-USER2_DN = 'uid=user2,' + DEFAULT_SUFFIX
d4e26e
-USER3_DN = 'uid=user3,' + DEFAULT_SUFFIX
d4e26e
-USER4_DN = 'uid=user4,' + DEFAULT_SUFFIX
d4e26e
-
d4e26e
-ROOTDSE_DEF_ATTR_LIST = ('namingContexts',
d4e26e
-                         'supportedLDAPVersion',
d4e26e
-                         'supportedControl',
d4e26e
-                         'supportedExtension',
d4e26e
-                         'supportedSASLMechanisms',
d4e26e
-                         'vendorName',
d4e26e
-                         'vendorVersion')
d4e26e
-
d4e26e
-
d4e26e
-@pytest.fixture(scope="module")
d4e26e
-def import_example_ldif(topology_st):
d4e26e
-    """Import the Example LDIF for the tests in this suite"""
d4e26e
-
d4e26e
-    log.info('Initializing the "basic" test suite')
d4e26e
-
d4e26e
-    ldif = '%s/Example.ldif' % get_data_dir(topology_st.standalone.prefix)
d4e26e
-    import_ldif = topology_st.standalone.get_ldif_dir() + "/Example.ldif"
d4e26e
-    shutil.copyfile(ldif, import_ldif)
d4e26e
-    topology_st.standalone.tasks.importLDIF(suffix=DEFAULT_SUFFIX,
d4e26e
-                                            input_file=import_ldif,
d4e26e
-                                            args={TASK_WAIT: True})
d4e26e
-
d4e26e
-
d4e26e
-@pytest.fixture(params=ROOTDSE_DEF_ATTR_LIST)
d4e26e
-def rootdse_attr(topology_st, request):
d4e26e
-    """Adds an attr from the list
d4e26e
-    as the default attr to the rootDSE
d4e26e
-    """
d4e26e
-    # Ensure the server is started and connected
d4e26e
-    topology_st.standalone.start()
d4e26e
-
d4e26e
-    RETURN_DEFAULT_OPATTR = "nsslapd-return-default-opattr"
d4e26e
-    rootdse_attr_name = ensure_bytes(request.param)
d4e26e
-
d4e26e
-    log.info("        Add the %s: %s to rootdse" % (RETURN_DEFAULT_OPATTR,
d4e26e
-                                                    rootdse_attr_name))
d4e26e
-    mod = [(ldap.MOD_ADD, RETURN_DEFAULT_OPATTR, rootdse_attr_name)]
d4e26e
-    try:
d4e26e
-        topology_st.standalone.modify_s("", mod)
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('Failed to add attr: error (%s)' % (e.message['desc']))
d4e26e
-        assert False
d4e26e
-
d4e26e
-    def fin():
d4e26e
-        log.info("        Delete the %s: %s from rootdse" % (RETURN_DEFAULT_OPATTR,
d4e26e
-                                                             rootdse_attr_name))
d4e26e
-        mod = [(ldap.MOD_DELETE, RETURN_DEFAULT_OPATTR, rootdse_attr_name)]
d4e26e
-        try:
d4e26e
-            topology_st.standalone.modify_s("", mod)
d4e26e
-        except ldap.LDAPError as e:
d4e26e
-            log.fatal('Failed to delete attr: error (%s)' % (e.message['desc']))
d4e26e
-            assert False
d4e26e
-
d4e26e
-    request.addfinalizer(fin)
d4e26e
-
d4e26e
-    return rootdse_attr_name
d4e26e
-
d4e26e
-
d4e26e
-def test_basic_ops(topology_st, import_example_ldif):
d4e26e
-    """Tests adds, mods, modrdns, and deletes operations
d4e26e
-
d4e26e
-    :id: 33f97f55-60bf-46c7-b880-6c488517ae19
d4e26e
-
d4e26e
-    :setup: Standalone instance
d4e26e
-
d4e26e
-    :steps:
d4e26e
-         1. Add 3 test users USER1, USER2 and USER3 to database
d4e26e
-         2. Modify (ADD, REPLACE and DELETE) description for USER1 in database
d4e26e
-         3. Rename USER1, USER2 and USER3 using Modrds
d4e26e
-         4. Delete test entries USER1, USER2 and USER3
d4e26e
-
d4e26e
-    :expectedresults:
d4e26e
-         1. Add operation should PASS.
d4e26e
-         2. Modify operations should PASS.
d4e26e
-         3. Rename operations should PASS.
d4e26e
-         4. Delete operations should PASS.
d4e26e
-    """
d4e26e
-    log.info('Running test_basic_ops...')
d4e26e
-    USER1_NEWDN = 'cn=user1'
d4e26e
-    USER2_NEWDN = 'cn=user2'
d4e26e
-    USER3_NEWDN = 'cn=user3'
d4e26e
-    NEW_SUPERIOR = 'ou=people,' + DEFAULT_SUFFIX
d4e26e
-    USER1_RDN_DN = 'cn=user1,' + DEFAULT_SUFFIX
d4e26e
-    USER2_RDN_DN = 'cn=user2,' + DEFAULT_SUFFIX
d4e26e
-    USER3_RDN_DN = 'cn=user3,' + NEW_SUPERIOR  # New superior test
d4e26e
-
d4e26e
-    #
d4e26e
-    # Adds#
d4e26e
-    try:
d4e26e
-        topology_st.standalone.add_s(Entry((USER1_DN,
d4e26e
-                                            {'objectclass': "top extensibleObject".split(),
d4e26e
-                                             'sn': '1',
d4e26e
-                                             'cn': 'user1',
d4e26e
-                                             'uid': 'user1',
d4e26e
-                                             'userpassword': 'password'})))
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.error('Failed to add test user' + USER1_DN + ': error ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        topology_st.standalone.add_s(Entry((USER2_DN,
d4e26e
-                                            {'objectclass': "top extensibleObject".split(),
d4e26e
-                                             'sn': '2',
d4e26e
-                                             'cn': 'user2',
d4e26e
-                                             'uid': 'user2',
d4e26e
-                                             'userpassword': 'password'})))
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.error('Failed to add test user' + USER2_DN + ': error ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        topology_st.standalone.add_s(Entry((USER3_DN,
d4e26e
-                                            {'objectclass': "top extensibleObject".split(),
d4e26e
-                                             'sn': '3',
d4e26e
-                                             'cn': 'user3',
d4e26e
-                                             'uid': 'user3',
d4e26e
-                                             'userpassword': 'password'})))
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.error('Failed to add test user' + USER3_DN + ': error ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    #
d4e26e
-    # Mods
d4e26e
-    #
d4e26e
-    try:
d4e26e
-        topology_st.standalone.modify_s(USER1_DN, [(ldap.MOD_ADD, 'description',
d4e26e
-                                                    b'New description')])
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.error('Failed to add description: error ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        topology_st.standalone.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'description',
d4e26e
-                                                    b'Modified description')])
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.error('Failed to modify description: error ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        topology_st.standalone.modify_s(USER1_DN, [(ldap.MOD_DELETE, 'description',
d4e26e
-                                                    None)])
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.error('Failed to delete description: error ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    #
d4e26e
-    # Modrdns
d4e26e
-    #
d4e26e
-    try:
d4e26e
-        topology_st.standalone.rename_s(USER1_DN, USER1_NEWDN, delold=1)
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.error('Failed to modrdn user1: error ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        topology_st.standalone.rename_s(USER2_DN, USER2_NEWDN, delold=0)
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.error('Failed to modrdn user2: error ' + e.message['desc'])
d4e26e
-        assert False  # Modrdn - New superior
d4e26e
-
d4e26e
-    try:
d4e26e
-        topology_st.standalone.rename_s(USER3_DN, USER3_NEWDN,
d4e26e
-                                        newsuperior=NEW_SUPERIOR, delold=1)
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.error('Failed to modrdn(new superior) user3: error ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-    #
d4e26e
-    # Deletes
d4e26e
-    #
d4e26e
-    try:
d4e26e
-        topology_st.standalone.delete_s(USER1_RDN_DN)
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.error('Failed to delete test entry1: ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        topology_st.standalone.delete_s(USER2_RDN_DN)
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.error('Failed to delete test entry2: ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        topology_st.standalone.delete_s(USER3_RDN_DN)
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.error('Failed to delete test entry3: ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-    log.info('test_basic_ops: PASSED')
d4e26e
-
d4e26e
-
d4e26e
-def test_basic_import_export(topology_st, import_example_ldif):
d4e26e
-    """Test online and offline LDIF import & export
d4e26e
-
d4e26e
-    :id: 3ceeea11-9235-4e20-b80e-7203b2c6e149
d4e26e
-
d4e26e
-    :setup: Standalone instance
d4e26e
-
d4e26e
-    :steps:
d4e26e
-         1. Generate a test ldif (50k entries)
d4e26e
-         2. Import test ldif file using Online import.
d4e26e
-         3. Import test ldif file using Offline import (ldif2db).
d4e26e
-         4. Export test ldif file using Online export.
d4e26e
-         5. Export test ldif file using Offline export (db2ldif).
d4e26e
-         6. Cleanup - Import the Example LDIF for the other tests in this suite
d4e26e
-
d4e26e
-    :expectedresults:
d4e26e
-         1. Test ldif file creation should PASS.
d4e26e
-         2. Online import should PASS.
d4e26e
-         3. Offline import should PASS.
d4e26e
-         4. Online export should PASS.
d4e26e
-         5. Offline export should PASS.
d4e26e
-         6. Cleanup should PASS.
d4e26e
-    """
d4e26e
-
d4e26e
-    log.info('Running test_basic_import_export...')
d4e26e
-
d4e26e
-    tmp_dir = '/tmp'
d4e26e
-
d4e26e
-    #
d4e26e
-    # Test online/offline LDIF imports
d4e26e
-    #
d4e26e
-    topology_st.standalone.start()
d4e26e
-
d4e26e
-    # Generate a test ldif (50k entries)
d4e26e
-    ldif_dir = topology_st.standalone.get_ldif_dir()
d4e26e
-    import_ldif = ldif_dir + '/basic_import.ldif'
d4e26e
-    dbgen(topology_st.standalone, 50000, import_ldif, DEFAULT_SUFFIX)
d4e26e
-
d4e26e
-    # Online
d4e26e
-    try:
d4e26e
-        topology_st.standalone.tasks.importLDIF(suffix=DEFAULT_SUFFIX,
d4e26e
-                                                input_file=import_ldif,
d4e26e
-                                                args={TASK_WAIT: True})
d4e26e
-    except ValueError:
d4e26e
-        log.fatal('test_basic_import_export: Online import failed')
d4e26e
-        assert False
d4e26e
-
d4e26e
-    # Offline
d4e26e
-    topology_st.standalone.stop()
d4e26e
-    if not topology_st.standalone.ldif2db(DEFAULT_BENAME, None, None, None, import_ldif):
d4e26e
-        log.fatal('test_basic_import_export: Offline import failed')
d4e26e
-        assert False
d4e26e
-    topology_st.standalone.start()
d4e26e
-
d4e26e
-    #
d4e26e
-    # Test online and offline LDIF export
d4e26e
-    #
d4e26e
-
d4e26e
-    # Online export
d4e26e
-    export_ldif = ldif_dir + '/export.ldif'
d4e26e
-    exportTask = Tasks(topology_st.standalone)
d4e26e
-    try:
d4e26e
-        args = {TASK_WAIT: True}
d4e26e
-        exportTask.exportLDIF(DEFAULT_SUFFIX, None, export_ldif, args)
d4e26e
-    except ValueError:
d4e26e
-        log.fatal('test_basic_import_export: Online export failed')
d4e26e
-        assert False
d4e26e
-
d4e26e
-    # Offline export
d4e26e
-    topology_st.standalone.stop()
d4e26e
-    if not topology_st.standalone.db2ldif(DEFAULT_BENAME, (DEFAULT_SUFFIX,),
d4e26e
-                                          None, None, None, export_ldif):
d4e26e
-        log.fatal('test_basic_import_export: Failed to run offline db2ldif')
d4e26e
-        assert False
d4e26e
-
d4e26e
-    topology_st.standalone.start()
d4e26e
-
d4e26e
-    #
d4e26e
-    # Cleanup - Import the Example LDIF for the other tests in this suite
d4e26e
-    #
d4e26e
-    ldif = '%s/Example.ldif' % get_data_dir(topology_st.standalone.prefix)
d4e26e
-    import_ldif = topology_st.standalone.get_ldif_dir() + "/Example.ldif"
d4e26e
-    shutil.copyfile(ldif, import_ldif)
d4e26e
-    try:
d4e26e
-        topology_st.standalone.tasks.importLDIF(suffix=DEFAULT_SUFFIX,
d4e26e
-                                                input_file=import_ldif,
d4e26e
-                                                args={TASK_WAIT: True})
d4e26e
-    except ValueError:
d4e26e
-        log.fatal('test_basic_import_export: Online import failed')
d4e26e
-        assert False
d4e26e
-
d4e26e
-    log.info('test_basic_import_export: PASSED')
d4e26e
-
d4e26e
-
d4e26e
-def test_basic_backup(topology_st, import_example_ldif):
d4e26e
-    """Tests online and offline backup and restore
d4e26e
-
d4e26e
-    :id: 0e9d91f8-8748-40b6-ab03-fbd1998eb985
d4e26e
-
d4e26e
-    :setup: Standalone instance and import example.ldif
d4e26e
-
d4e26e
-    :steps:
d4e26e
-         1. Test online backup using db2bak.
d4e26e
-         2. Test online restore using bak2db.
d4e26e
-         3. Test offline backup using db2bak.
d4e26e
-         4. Test offline restore using bak2db.
d4e26e
-
d4e26e
-    :expectedresults:
d4e26e
-         1. Online backup should PASS.
d4e26e
-         2. Online restore should PASS.
d4e26e
-         3. Offline backup should PASS.
d4e26e
-         4. Offline restore should PASS.
d4e26e
-    """
d4e26e
-
d4e26e
-    log.info('Running test_basic_backup...')
d4e26e
-
d4e26e
-    backup_dir = topology_st.standalone.get_bak_dir() + '/backup_test'
d4e26e
-
d4e26e
-    # Test online backup
d4e26e
-    try:
d4e26e
-        topology_st.standalone.tasks.db2bak(backup_dir=backup_dir,
d4e26e
-                                            args={TASK_WAIT: True})
d4e26e
-    except ValueError:
d4e26e
-        log.fatal('test_basic_backup: Online backup failed')
d4e26e
-        assert False
d4e26e
-
d4e26e
-    # Test online restore
d4e26e
-    try:
d4e26e
-        topology_st.standalone.tasks.bak2db(backup_dir=backup_dir,
d4e26e
-                                            args={TASK_WAIT: True})
d4e26e
-    except ValueError:
d4e26e
-        log.fatal('test_basic_backup: Online restore failed')
d4e26e
-        assert False
d4e26e
-
d4e26e
-    # Test offline backup
d4e26e
-    topology_st.standalone.stop()
d4e26e
-    if not topology_st.standalone.db2bak(backup_dir):
d4e26e
-        log.fatal('test_basic_backup: Offline backup failed')
d4e26e
-        assert False
d4e26e
-
d4e26e
-    # Test offline restore
d4e26e
-    if not topology_st.standalone.bak2db(backup_dir):
d4e26e
-        log.fatal('test_basic_backup: Offline backup failed')
d4e26e
-        assert False
d4e26e
-    topology_st.standalone.start()
d4e26e
-
d4e26e
-    log.info('test_basic_backup: PASSED')
d4e26e
-
d4e26e
-
d4e26e
-def test_basic_acl(topology_st, import_example_ldif):
d4e26e
-    """Run some basic access control (ACL) tests
d4e26e
-
d4e26e
-    :id: 4f4e705f-32f4-4065-b3a8-2b0c2525798b
d4e26e
-
d4e26e
-    :setup: Standalone instance
d4e26e
-
d4e26e
-    :steps:
d4e26e
-         1. Add two test users USER1_DN and USER2_DN.
d4e26e
-         2. Add an aci that denies USER1 from doing anything.
d4e26e
-         3. Set the default anonymous access for USER2.
d4e26e
-         4. Try searching entries using USER1.
d4e26e
-         5. Try searching entries using USER2.
d4e26e
-         6. Try searching entries using root dn.
d4e26e
-         7. Cleanup - delete test users and test ACI.
d4e26e
-
d4e26e
-    :expectedresults:
d4e26e
-         1. Test Users should be added.
d4e26e
-         2. ACI should be added.
d4e26e
-         3. This operation should PASS.
d4e26e
-         4. USER1 should not be able to search anything.
d4e26e
-         5. USER2 should be able to search everything except password.
d4e26e
-         6. RootDN should be allowed to search everything.
d4e26e
-         7. Cleanup should PASS.
d4e26e
-    """
d4e26e
-
d4e26e
-    """Run some basic access control(ACL) tests"""
d4e26e
-    log.info('Running test_basic_acl...')
d4e26e
-
d4e26e
-    DENY_ACI = ensure_bytes('(targetattr = "*")(version 3.0;acl "deny user";deny (all)(userdn = "ldap:///%s");)' % USER1_DN)
d4e26e
-
d4e26e
-    #
d4e26e
-    # Add two users
d4e26e
-    #
d4e26e
-    try:
d4e26e
-        topology_st.standalone.add_s(Entry((USER1_DN,
d4e26e
-                                            {'objectclass': "top extensibleObject".split(),
d4e26e
-                                             'sn': '1',
d4e26e
-                                             'cn': 'user 1',
d4e26e
-                                             'uid': 'user1',
d4e26e
-                                             'userpassword': PASSWORD})))
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_acl: Failed to add test user ' + USER1_DN +
d4e26e
-                  ': error ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        topology_st.standalone.add_s(Entry((USER2_DN,
d4e26e
-                                            {'objectclass': "top extensibleObject".split(),
d4e26e
-                                             'sn': '2',
d4e26e
-                                             'cn': 'user 2',
d4e26e
-                                             'uid': 'user2',
d4e26e
-                                             'userpassword': PASSWORD})))
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_acl: Failed to add test user ' + USER1_DN +
d4e26e
-                  ': error ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    #
d4e26e
-    # Add an aci that denies USER1 from doing anything,
d4e26e
-    # and also set the default anonymous access
d4e26e
-    #
d4e26e
-    try:
d4e26e
-        topology_st.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_ADD, 'aci', DENY_ACI)])
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_acl: Failed to add DENY ACI: error ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    #
d4e26e
-    # Make sure USER1_DN can not search anything, but USER2_dn can...
d4e26e
-    #
d4e26e
-    try:
d4e26e
-        topology_st.standalone.simple_bind_s(USER1_DN, PASSWORD)
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_acl: Failed to bind as user1, error: ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        entries = topology_st.standalone.search_s(DEFAULT_SUFFIX,
d4e26e
-                                                  ldap.SCOPE_SUBTREE,
d4e26e
-                                                  '(uid=*)')
d4e26e
-        if entries:
d4e26e
-            log.fatal('test_basic_acl: User1 was incorrectly able to search the suffix!')
d4e26e
-            assert False
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_acl: Search suffix failed(as user1): ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    # Now try user2...  Also check that userpassword is stripped out
d4e26e
-    try:
d4e26e
-        topology_st.standalone.simple_bind_s(USER2_DN, PASSWORD)
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_acl: Failed to bind as user2, error: ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        entries = topology_st.standalone.search_s(DEFAULT_SUFFIX,
d4e26e
-                                                  ldap.SCOPE_SUBTREE,
d4e26e
-                                                  '(uid=user1)')
d4e26e
-        if not entries:
d4e26e
-            log.fatal('test_basic_acl: User1 incorrectly not able to search the suffix')
d4e26e
-            assert False
d4e26e
-        if entries[0].hasAttr('userpassword'):
d4e26e
-            # The default anonymous access aci should have stripped out userpassword
d4e26e
-            log.fatal('test_basic_acl: User2 was incorrectly able to see userpassword')
d4e26e
-            assert False
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_acl: Search for user1 failed(as user2): ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    # Make sure RootDN can also search (this also resets the bind dn to the
d4e26e
-    # Root DN for future operations)
d4e26e
-    try:
d4e26e
-        topology_st.standalone.simple_bind_s(DN_DM, PW_DM)
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_acl: Failed to bind as ROotDN, error: ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        entries = topology_st.standalone.search_s(DEFAULT_SUFFIX,
d4e26e
-                                                  ldap.SCOPE_SUBTREE,
d4e26e
-                                                  '(uid=*)')
d4e26e
-        if not entries:
d4e26e
-            log.fatal('test_basic_acl: Root DN incorrectly not able to search the suffix')
d4e26e
-            assert False
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_acl: Search for user1 failed(as user2): ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    #
d4e26e
-    # Cleanup
d4e26e
-    #
d4e26e
-    try:
d4e26e
-        topology_st.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_DELETE, 'aci', DENY_ACI)])
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_acl: Failed to delete DENY ACI: error ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        topology_st.standalone.delete_s(USER1_DN)
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_acl: Failed to delete test entry1: ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        topology_st.standalone.delete_s(USER2_DN)
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_acl: Failed to delete test entry2: ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    log.info('test_basic_acl: PASSED')
d4e26e
-
d4e26e
-
d4e26e
-def test_basic_searches(topology_st, import_example_ldif):
d4e26e
-    """Tests basic search operations with filters.
d4e26e
-
d4e26e
-    :id: 426a59ff-49b8-4a70-b377-0c0634a29b6f
d4e26e
-
d4e26e
-    :setup: Standalone instance, add example.ldif to the database
d4e26e
-
d4e26e
-    :steps:
d4e26e
-         1. Execute search command while using different filters.
d4e26e
-         2. Check number of entries returned by search filters.
d4e26e
-
d4e26e
-    :expectedresults:
d4e26e
-         1. Search command should PASS.
d4e26e
-         2. Number of result entries returned should match number of the database entries according to the search filter.
d4e26e
-    """
d4e26e
-
d4e26e
-    log.info('Running test_basic_searches...')
d4e26e
-
d4e26e
-    filters = (('(uid=scarter)', 1),
d4e26e
-               ('(uid=tmorris*)', 1),
d4e26e
-               ('(uid=*hunt*)', 4),
d4e26e
-               ('(uid=*cope)', 2),
d4e26e
-               ('(mail=*)', 150),
d4e26e
-               ('(roomnumber>=4000)', 35),
d4e26e
-               ('(roomnumber<=4000)', 115),
d4e26e
-               ('(&(roomnumber>=4000)(roomnumber<=4500))', 18),
d4e26e
-               ('(!(l=sunnyvale))', 120),
d4e26e
-               ('(&(uid=t*)(l=santa clara))', 7),
d4e26e
-               ('(|(uid=k*)(uid=r*))', 18),
d4e26e
-               ('(|(uid=t*)(l=sunnyvale))', 50),
d4e26e
-               ('(&(!(uid=r*))(ou=people))', 139),
d4e26e
-               ('(&(uid=m*)(l=sunnyvale)(ou=people)(mail=*example*)(roomNumber=*))', 3),
d4e26e
-               ('(&(|(uid=m*)(l=santa clara))(roomNumber=22*))', 5),
d4e26e
-               ('(&(|(uid=m*)(l=santa clara))(roomNumber=22*)(!(roomnumber=2254)))', 4),)
d4e26e
-
d4e26e
-    for (search_filter, search_result) in filters:
d4e26e
-        try:
d4e26e
-            entries = topology_st.standalone.search_s(DEFAULT_SUFFIX,
d4e26e
-                                                      ldap.SCOPE_SUBTREE,
d4e26e
-                                                      search_filter)
d4e26e
-            if len(entries) != search_result:
d4e26e
-                log.fatal('test_basic_searches: An incorrect number of entries\
d4e26e
-                        was returned from filter (%s): (%d) expected (%d)' %
d4e26e
-                          (search_filter, len(entries), search_result))
d4e26e
-                assert False
d4e26e
-        except ldap.LDAPError as e:
d4e26e
-            log.fatal('Search failed: ' + e.message['desc'])
d4e26e
-            assert False
d4e26e
-
d4e26e
-    log.info('test_basic_searches: PASSED')
d4e26e
-
d4e26e
-
d4e26e
-@pytest.fixture(scope="module")
d4e26e
-def add_test_entry(topology_st, request):
d4e26e
-    # Add test entry
d4e26e
-    topology_st.standalone.add_s(Entry((USER4_DN,
d4e26e
-                                        {'objectclass': "top extensibleObject".split(),
d4e26e
-                                         'cn': 'user1', 'uid': 'user1'})))
d4e26e
-
d4e26e
-
d4e26e
-search_params = [(['1.1'], 'cn', False),
d4e26e
-                 (['1.1', 'cn'], 'cn', True),
d4e26e
-                 (['+'], 'nsUniqueId', True),
d4e26e
-                 (['*'], 'cn', True),
d4e26e
-                 (['cn'], 'cn', True)]
d4e26e
-@pytest.mark.parametrize("attrs, attr, present", search_params)
d4e26e
-def test_search_req_attrs(topology_st, add_test_entry, attrs, attr, present):
d4e26e
-    """Test requested attributes in search operations.
d4e26e
-    :id: 426a59ff-49b8-4a70-b377-0c0634a29b6e
d4e26e
-    :setup: Standalone instance
d4e26e
-    :steps:
d4e26e
-         1. Test "1.1" does not return any attributes.
d4e26e
-         2. Test "1.1" is ignored if there are other requested attributes
d4e26e
-         3. Test "+" returns all operational attributes
d4e26e
-         4. Test "*" returns all attributes
d4e26e
-         5. Test requested attributes
d4e26e
-
d4e26e
-    :expectedresults:
d4e26e
-         1. Success
d4e26e
-         2. Success
d4e26e
-         3. Success
d4e26e
-         4. Success
d4e26e
-         5. Success
d4e26e
-    """
d4e26e
-
d4e26e
-    log.info("Testing attrs: {} attr: {} present: {}".format(attrs, attr, present))
d4e26e
-    entry = topology_st.standalone.search_s(USER4_DN,
d4e26e
-                                            ldap.SCOPE_BASE,
d4e26e
-                                            'objectclass=top',
d4e26e
-                                            attrs)
d4e26e
-    if present:
d4e26e
-        assert entry[0].hasAttr(attr)
d4e26e
-    else:
d4e26e
-        assert not entry[0].hasAttr(attr)
d4e26e
-
d4e26e
-
d4e26e
-def test_basic_referrals(topology_st, import_example_ldif):
d4e26e
-    """Test LDAP server in referral mode.
d4e26e
-
d4e26e
-    :id: c586aede-7ac3-4e8d-a1cf-bfa8b8d78cc2
d4e26e
-
d4e26e
-    :setup: Standalone instance
d4e26e
-
d4e26e
-    :steps:
d4e26e
-         1. Set the referral and the backenidealyd state
d4e26e
-         2. Set backend state to referral mode.
d4e26e
-         3. Set server to not follow referral.
d4e26e
-         4. Search using referral.
d4e26e
-         5. Make sure server can restart in referral mode.
d4e26e
-         6. Cleanup - Delete referral.
d4e26e
-
d4e26e
-    :expectedresults:
d4e26e
-         1. Set the referral, and the backend state should PASS.
d4e26e
-         2. Set backend state to referral mode should PASS.
d4e26e
-         3. Set server to not follow referral should PASS.
d4e26e
-         4. referral error(10) should occur.
d4e26e
-         5. Restart should PASS.
d4e26e
-         6. Cleanup should PASS.
d4e26e
-    """
d4e26e
-
d4e26e
-    log.info('Running test_basic_referrals...')
d4e26e
-    SUFFIX_CONFIG = 'cn="dc=example,dc=com",cn=mapping tree,cn=config'
d4e26e
-    #
d4e26e
-    # Set the referral, and the backend state
d4e26e
-    #
d4e26e
-    try:
d4e26e
-        topology_st.standalone.modify_s(SUFFIX_CONFIG,
d4e26e
-                                        [(ldap.MOD_REPLACE,
d4e26e
-                                          'nsslapd-referral',
d4e26e
-                                          b'ldap://localhost.localdomain:389/o%3dnetscaperoot')])
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_referrals: Failed to set referral: error ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        topology_st.standalone.modify_s(SUFFIX_CONFIG, [(ldap.MOD_REPLACE,
d4e26e
-                                                         'nsslapd-state', b'Referral')])
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_referrals: Failed to set backend state: error '
d4e26e
-                  + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    #
d4e26e
-    # Test that a referral error is returned
d4e26e
-    #
d4e26e
-    topology_st.standalone.set_option(ldap.OPT_REFERRALS, 0)  # Do not follow referral
d4e26e
-    try:
d4e26e
-        topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'objectclass=top')
d4e26e
-    except ldap.REFERRAL:
d4e26e
-        pass
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_referrals: Search failed: ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    #
d4e26e
-    # Make sure server can restart in referral mode
d4e26e
-    #
d4e26e
-    topology_st.standalone.restart(timeout=10)
d4e26e
-
d4e26e
-    #
d4e26e
-    # Cleanup
d4e26e
-    #
d4e26e
-    try:
d4e26e
-        topology_st.standalone.modify_s(SUFFIX_CONFIG, [(ldap.MOD_REPLACE,
d4e26e
-                                                         'nsslapd-state', b'Backend')])
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_referrals: Failed to set backend state: error '
d4e26e
-                  + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-    try:
d4e26e
-        topology_st.standalone.modify_s(SUFFIX_CONFIG, [(ldap.MOD_DELETE,
d4e26e
-                                                         'nsslapd-referral', None)])
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('test_basic_referrals: Failed to delete referral: error '
d4e26e
-                  + e.message['desc'])
d4e26e
-        assert False
d4e26e
-    topology_st.standalone.set_option(ldap.OPT_REFERRALS, 1)
d4e26e
-
d4e26e
-    log.info('test_basic_referrals: PASSED')
d4e26e
-
d4e26e
-
d4e26e
-def test_basic_systemctl(topology_st, import_example_ldif):
d4e26e
-    """Tests systemctl/lib389 can stop and start the server.
d4e26e
-
d4e26e
-    :id: a92a7438-ecfa-4583-a89c-5fbfc0220b69
d4e26e
-
d4e26e
-    :setup: Standalone instance
d4e26e
-
d4e26e
-    :steps:
d4e26e
-         1. Stop the server.
d4e26e
-         2. Start the server.
d4e26e
-         3. Stop the server, break the dse.ldif and dse.ldif.bak, so a start fails.
d4e26e
-         4. Verify that systemctl detects the failed start.
d4e26e
-         5. Fix the dse.ldif, and make sure the server starts up.
d4e26e
-         6. Verify systemctl correctly identifies the successful start.
d4e26e
-
d4e26e
-    :expectedresults:
d4e26e
-         1. Server should be stopped.
d4e26e
-         2. Server should start
d4e26e
-         3. Stop should work but start after breaking dse.ldif should fail.
d4e26e
-         4. Systemctl should be able to detect the failed start.
d4e26e
-         5. Server should start.
d4e26e
-         6. Systemctl should be able to detect the successful start.
d4e26e
-    """
d4e26e
-
d4e26e
-    log.info('Running test_basic_systemctl...')
d4e26e
-
d4e26e
-    config_dir = topology_st.standalone.get_config_dir()
d4e26e
-
d4e26e
-    #
d4e26e
-    # Stop the server
d4e26e
-    #
d4e26e
-    log.info('Stopping the server...')
d4e26e
-    topology_st.standalone.stop()
d4e26e
-    log.info('Stopped the server.')
d4e26e
-
d4e26e
-    #
d4e26e
-    # Start the server
d4e26e
-    #
d4e26e
-    log.info('Starting the server...')
d4e26e
-    topology_st.standalone.start()
d4e26e
-    log.info('Started the server.')
d4e26e
-
d4e26e
-    #
d4e26e
-    # Stop the server, break the dse.ldif so a start fails,
d4e26e
-    # and verify that systemctl detects the failed start
d4e26e
-    #
d4e26e
-    log.info('Stopping the server...')
d4e26e
-    topology_st.standalone.stop()
d4e26e
-    log.info('Stopped the server before breaking the dse.ldif.')
d4e26e
-
d4e26e
-    shutil.copy(config_dir + '/dse.ldif', config_dir + '/dse.ldif.correct')
d4e26e
-    open(config_dir + '/dse.ldif', 'w').close()
d4e26e
-    # We need to kill the .bak file too, DS is just too smart!
d4e26e
-    open(config_dir + '/dse.ldif.bak', 'w').close()
d4e26e
-
d4e26e
-    log.info('Attempting to start the server with broken dse.ldif...')
d4e26e
-    try:
d4e26e
-        topology_st.standalone.start()
d4e26e
-    except Exception as e:
d4e26e
-        log.info('Server failed to start as expected: ' + str(e))
d4e26e
-    log.info('Check the status...')
d4e26e
-    assert (not topology_st.standalone.status())
d4e26e
-    log.info('Server failed to start as expected')
d4e26e
-    time.sleep(5)
d4e26e
-
d4e26e
-    #
d4e26e
-    # Fix the dse.ldif, and make sure the server starts up,
d4e26e
-    # and systemctl correctly identifies the successful start
d4e26e
-    #
d4e26e
-    shutil.copy(config_dir + '/dse.ldif.correct', config_dir + '/dse.ldif')
d4e26e
-    log.info('Starting the server with good dse.ldif...')
d4e26e
-    topology_st.standalone.start()
d4e26e
-    log.info('Check the status...')
d4e26e
-    assert (topology_st.standalone.status())
d4e26e
-    log.info('Server started after fixing dse.ldif.')
d4e26e
-
d4e26e
-    log.info('test_basic_systemctl: PASSED')
d4e26e
-
d4e26e
-
d4e26e
-def test_basic_ldapagent(topology_st, import_example_ldif):
d4e26e
-    """Tests that the ldap agent starts
d4e26e
-
d4e26e
-    :id: da1d1846-8fc4-4b8c-8e53-4c9c16eff1ba
d4e26e
-
d4e26e
-    :setup: Standalone instance
d4e26e
-
d4e26e
-    :steps:
d4e26e
-         1. Start SNMP ldap agent using command.
d4e26e
-         2. Cleanup - Kill SNMP agent process.
d4e26e
-
d4e26e
-    :expectedresults:
d4e26e
-         1. SNMP agent should start.
d4e26e
-         2. SNMP agent process should be successfully killed.
d4e26e
-    """
d4e26e
-
d4e26e
-    log.info('Running test_basic_ldapagent...')
d4e26e
-
d4e26e
-    var_dir = topology_st.standalone.get_local_state_dir()
d4e26e
-
d4e26e
-    config_file = os.path.join(topology_st.standalone.get_sysconf_dir(), 'dirsrv/config/agent.conf')
d4e26e
-
d4e26e
-    agent_config_file = open(config_file, 'w')
d4e26e
-    agent_config_file.write('agentx-master ' + var_dir + '/agentx/master\n')
d4e26e
-    agent_config_file.write('agent-logdir ' + var_dir + '/log/dirsrv\n')
d4e26e
-    agent_config_file.write('server slapd-' + topology_st.standalone.serverid + '\n')
d4e26e
-    agent_config_file.close()
d4e26e
-
d4e26e
-    # Remember, this is *forking*
d4e26e
-    check_output([os.path.join(topology_st.standalone.get_sbin_dir(), 'ldap-agent'), config_file])
d4e26e
-    # First kill any previous agents ....
d4e26e
-    pidpath = os.path.join(var_dir, 'run/ldap-agent.pid')
d4e26e
-    pid = None
d4e26e
-    with open(pidpath, 'r') as pf:
d4e26e
-        pid = pf.readlines()[0].strip()
d4e26e
-    if pid:
d4e26e
-        log.debug('test_basic_ldapagent: Terminating agent %s', pid)
d4e26e
-        check_output(['kill', pid])
d4e26e
-
d4e26e
-    log.info('test_basic_ldapagent: PASSED')
d4e26e
-
d4e26e
-
d4e26e
-def test_basic_dse(topology_st, import_example_ldif):
d4e26e
-    """Tests that the dse.ldif is not wiped out after the process is killed (bug 910581)
d4e26e
-
d4e26e
-    :id: 10f141da-9b22-443a-885c-87271dcd7a59
d4e26e
-
d4e26e
-    :setup: Standalone instance
d4e26e
-
d4e26e
-    :steps:
d4e26e
-         1. Check out pid of ns-slapd process and Kill ns-slapd process.
d4e26e
-         2. Check the contents of dse.ldif file.
d4e26e
-         3. Start server.
d4e26e
-
d4e26e
-    :expectedresults:
d4e26e
-         1. ns-slapd process should be killed.
d4e26e
-         2. dse.ldif should not be corrupted.
d4e26e
-         3. Server should start successfully.
d4e26e
-    """
d4e26e
-    log.info('Running test_basic_dse...')
d4e26e
-
d4e26e
-    dse_file = topology_st.standalone.confdir + '/dse.ldif'
d4e26e
-    pid = check_output(['pidof', '-s', 'ns-slapd']).strip()
d4e26e
-    check_output(['sudo', 'kill', '-9', ensure_str(pid)])
d4e26e
-    if os.path.getsize(dse_file) == 0:
d4e26e
-        log.fatal('test_basic_dse: dse.ldif\'s content was incorrectly removed!')
d4e26e
-        assert False
d4e26e
-
d4e26e
-    topology_st.standalone.start(timeout=60)
d4e26e
-    log.info('dse.ldif was not corrupted, and the server was restarted')
d4e26e
-
d4e26e
-    log.info('test_basic_dse: PASSED')
d4e26e
-    # Give the server time to startup, in some conditions this can be racey without systemd notification. Only affects this one test though...
d4e26e
-    time.sleep(10)
d4e26e
-
d4e26e
-
d4e26e
-@pytest.mark.parametrize("rootdse_attr_name", ROOTDSE_DEF_ATTR_LIST)
d4e26e
-def test_def_rootdse_attr(topology_st, import_example_ldif, rootdse_attr_name):
d4e26e
-    """Tests that operational attributes are not returned by default in rootDSE searches
d4e26e
-
d4e26e
-    :id: 4fee33cc-4019-4c27-89e8-998e6c770dc0
d4e26e
-
d4e26e
-    :setup: Standalone instance
d4e26e
-
d4e26e
-    :steps:
d4e26e
-         1. Make an ldapsearch for rootdse attribute
d4e26e
-         2. Check the returned entries.
d4e26e
-
d4e26e
-    :expectedresults:
d4e26e
-         1. Search should not fail
d4e26e
-         2. Operational attributes should not be returned.
d4e26e
-    """
d4e26e
-
d4e26e
-    topology_st.standalone.start()
d4e26e
-
d4e26e
-    log.info(" Assert rootdse search hasn't %s attr" % rootdse_attr_name)
d4e26e
-    try:
d4e26e
-        entry = topology_st.standalone.search_s("", ldap.SCOPE_BASE)[0]
d4e26e
-        assert not entry.hasAttr(rootdse_attr_name)
d4e26e
-
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('Search failed, error: ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-
d4e26e
-def test_mod_def_rootdse_attr(topology_st, import_example_ldif, rootdse_attr):
d4e26e
-    """Tests that operational attributes are returned by default in rootDSE searches after config modification
d4e26e
-
d4e26e
-   :id: c7831e04-f458-4e23-83c7-b6f66109f639
d4e26e
-
d4e26e
-   :setup: Standalone instance and we are using rootdse_attr fixture which 
d4e26e
-adds nsslapd-return-default-opattr attr with value of one operation attribute.
d4e26e
-
d4e26e
-   :steps:
d4e26e
-         1. Make an ldapsearch for rootdse attribute
d4e26e
-         2. Check the returned entries.
d4e26e
-
d4e26e
-   :expectedresults:
d4e26e
-         1. Search should not fail
d4e26e
-         2. Operational attributes should be returned after the config modification
d4e26e
-   """
d4e26e
-
d4e26e
-    log.info(" Assert rootdse search has %s attr" % rootdse_attr)
d4e26e
-    try:
d4e26e
-        entry = topology_st.standalone.search_s("", ldap.SCOPE_BASE)[0]
d4e26e
-        assert entry.hasAttr(rootdse_attr)
d4e26e
-
d4e26e
-    except ldap.LDAPError as e:
d4e26e
-        log.fatal('Search failed, error: ' + e.message['desc'])
d4e26e
-        assert False
d4e26e
-
d4e26e
-
d4e26e
-@pytest.fixture(scope="module")
d4e26e
-def create_users(topology_st):
d4e26e
-    """Add users to the default suffix
d4e26e
-    """
d4e26e
-
d4e26e
-    users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX)
d4e26e
-    user_names = ["Directory", "Server", "389", "lib389", "pytest"]
d4e26e
-
d4e26e
-    log.info('Adding 5 test users')
d4e26e
-    for name in user_names:
d4e26e
-        user = users.create(properties={
d4e26e
-            'uid': name,
d4e26e
-            'sn': name,
d4e26e
-            'cn': name,
d4e26e
-            'uidNumber': '1000',
d4e26e
-            'gidNumber': '1000',
d4e26e
-            'homeDirectory': '/home/%s' % name,
d4e26e
-            'mail': '%s@example.com' % name,
d4e26e
-            'userpassword': 'pass%s' % name,
d4e26e
-        })
d4e26e
-
d4e26e
-
d4e26e
-def test_basic_anonymous_search(topology_st, create_users):
d4e26e
-    """Tests basic anonymous search operations
d4e26e
-
d4e26e
-    :id: c7831e04-f458-4e50-83c7-b6f77109f639
d4e26e
-    :setup: Standalone instance
d4e26e
-            Add 5 test users with different user names
d4e26e
-    :steps:
d4e26e
-         1. Execute anonymous search with different filters
d4e26e
-    :expectedresults:
d4e26e
-         1. Search should be successful
d4e26e
-    """
d4e26e
-
d4e26e
-    filters = ["uid=Directory", "(|(uid=S*)(uid=3*))", "(&(uid=l*)(mail=l*))", "(&(!(uid=D*))(ou=People))"]
d4e26e
-    log.info("Execute anonymous search with different filters")
d4e26e
-    for filtr in filters:
d4e26e
-        entries = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, filtr)
d4e26e
-        assert len(entries) != 0
d4e26e
-
d4e26e
-
d4e26e
-@pytest.mark.ds604
d4e26e
-@pytest.mark.bz915801
d4e26e
-def test_search_original_type(topology_st, create_users):
d4e26e
-    """Test ldapsearch returning original attributes
d4e26e
-        using nsslapd-search-return-original-type-switch
d4e26e
-
d4e26e
-    :id: d7831d04-f558-4e50-93c7-b6f77109f640
d4e26e
-    :setup: Standalone instance
d4e26e
-            Add some test entries
d4e26e
-    :steps:
d4e26e
-         1. Set nsslapd-search-return-original-type-switch to ON
d4e26e
-         2. Check that ldapsearch *does* return unknown attributes
d4e26e
-         3. Turn off nsslapd-search-return-original-type-switch
d4e26e
-         4. Check that ldapsearch doesn't return any unknown attributes
d4e26e
-    :expectedresults:
d4e26e
-         1. nsslapd-search-return-original-type-switch should be set to ON
d4e26e
-         2. ldapsearch should return unknown attributes
d4e26e
-         3. nsslapd-search-return-original-type-switch should be OFF
d4e26e
-         4. ldapsearch should not return any unknown attributes
d4e26e
-    """
d4e26e
-
d4e26e
-    log.info("Set nsslapd-search-return-original-type-switch to ON")
d4e26e
-    topology_st.standalone.config.set('nsslapd-search-return-original-type-switch', 'on')
d4e26e
-
d4e26e
-    log.info("Check that ldapsearch *does* return unknown attributes")
d4e26e
-    entries = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'uid=Directory',
d4e26e
-                                              ['objectclass overflow', 'unknown'])
d4e26e
-    assert "objectclass overflow" in entries[0].getAttrs()
d4e26e
-
d4e26e
-    log.info("Set nsslapd-search-return-original-type-switch to Off")
d4e26e
-    topology_st.standalone.config.set('nsslapd-search-return-original-type-switch', 'off')
d4e26e
-    log.info("Check that ldapsearch *does not* return unknown attributes")
d4e26e
-    entries = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'uid=Directory',
d4e26e
-                                              ['objectclass overflow', 'unknown'])
d4e26e
-    assert "objectclass overflow" not in entries[0].getAttrs()
d4e26e
-
d4e26e
-
d4e26e
-@pytest.mark.bz192901
d4e26e
-def test_search_ou(topology_st):
d4e26e
-    """Test that DS should not return an entry that does not match the filter
d4e26e
-
d4e26e
-    :id: d7831d05-f117-4e89-93c7-b6f77109f640
d4e26e
-    :setup: Standalone instance
d4e26e
-    :steps:
d4e26e
-         1. Create an OU entry without sub entries
d4e26e
-         2. Search from the OU with the filter that does not match the OU
d4e26e
-    :expectedresults:
d4e26e
-         1. Creation of OU should be successful
d4e26e
-         2. Search should not return any results
d4e26e
-    """
d4e26e
-
d4e26e
-    log.info("Create a test OU without sub entries")
d4e26e
-    ou = OrganizationalUnits(topology_st.standalone, DEFAULT_SUFFIX)
d4e26e
-    ou.create(properties={
d4e26e
-        'ou': 'test_ou',
d4e26e
-    })
d4e26e
-
d4e26e
-    search_base = ("ou=test_ou,%s" % DEFAULT_SUFFIX)
d4e26e
-    log.info("Search from the OU with the filter that does not match the OU, it should not return anything")
d4e26e
-    entries = topology_st.standalone.search_s(search_base, ldap.SCOPE_SUBTREE, 'uid=*', ['dn'])
d4e26e
-    assert len(entries) == 0
d4e26e
-
d4e26e
-
d4e26e
-@pytest.mark.bz1044135
d4e26e
-@pytest.mark.ds47319
d4e26e
-def test_connection_buffer_size(topology_st):
d4e26e
-    """Test connection buffer size adjustable with different values(valid values and invalid)
d4e26e
-
d4e26e
-    :id: e7831d05-f117-4ec9-1203-b6f77109f117
d4e26e
-    :setup: Standalone instance
d4e26e
-    :steps:
d4e26e
-         1. Set nsslapd-connection-buffer to some valid values (2, 0 , 1)
d4e26e
-         2. Set nsslapd-connection-buffer to some invalid values (-1, a)
d4e26e
-    :expectedresults:
d4e26e
-         1. This should pass
d4e26e
-         2. This should fail
d4e26e
-    """
d4e26e
-
d4e26e
-    valid_values = ['2', '0', '1']
d4e26e
-    for value in valid_values:
d4e26e
-        topology_st.standalone.config.replace('nsslapd-connection-buffer', value)
d4e26e
-
d4e26e
-    invalid_values = ['-1', 'a']
d4e26e
-    for value in invalid_values:
d4e26e
-        with pytest.raises(ldap.OPERATIONS_ERROR):
d4e26e
-            topology_st.standalone.config.replace('nsslapd-connection-buffer', value)
d4e26e
-
d4e26e
-@pytest.mark.bz1637439
d4e26e
-def test_critical_msg_on_empty_range_idl(topology_st):
d4e26e
-    """Doing a range index lookup should not report a critical message even if IDL is empty
d4e26e
-
d4e26e
-    :id: a07a2222-0551-44a6-b113-401d23799364
d4e26e
-    :setup: Standalone instance
d4e26e
-    :steps:
d4e26e
-         1. Create an index for internationalISDNNumber. (attribute chosen because it is
d4e26e
-         unlikely that previous tests used it)
d4e26e
-         2. telephoneNumber being indexed by default create 20 users without telephoneNumber
d4e26e
-         3. add a telephoneNumber value and delete it to trigger an empty index database
d4e26e
-         4. Do a search that triggers a range lookup on empty telephoneNumber
d4e26e
-         5. Check that the critical message is not logged in error logs
d4e26e
-    :expectedresults:
d4e26e
-         1. This should pass
d4e26e
-         2. This should pass
d4e26e
-         3. This should pass
d4e26e
-         4. This should pass on normal build but could abort a debug build
d4e26e
-         4. This should pass
d4e26e
-    """
d4e26e
-    indexedAttr = 'internationalISDNNumber'
d4e26e
-
d4e26e
-    # Step 1
d4e26e
-    from lib389.index import Indexes
d4e26e
-
d4e26e
-    indexes = Indexes(topology_st.standalone)
d4e26e
-    indexes.create(properties={
d4e26e
-        'cn': indexedAttr,
d4e26e
-        'nsSystemIndex': 'false',
d4e26e
-        'nsIndexType': 'eq'
d4e26e
-        })
d4e26e
-    topology_st.standalone.restart()
d4e26e
-
d4e26e
-    # Step 2
d4e26e
-    users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX)
d4e26e
-    log.info('Adding 20 users without "%s"' % indexedAttr)
d4e26e
-    for i in range(20):
d4e26e
-        name = 'user_%d' % i
d4e26e
-        last_user = users.create(properties={
d4e26e
-            'uid': name,
d4e26e
-            'sn': name,
d4e26e
-            'cn': name,
d4e26e
-            'uidNumber': '1000',
d4e26e
-            'gidNumber': '1000',
d4e26e
-            'homeDirectory': '/home/%s' % name,
d4e26e
-            'mail': '%s@example.com' % name,
d4e26e
-            'userpassword': 'pass%s' % name,
d4e26e
-        })
d4e26e
-
d4e26e
-    # Step 3
d4e26e
-    # required update to create the indexAttr (i.e. 'loginShell') database, and then make it empty
d4e26e
-    topology_st.standalone.modify_s(last_user.dn, [(ldap.MOD_ADD, indexedAttr, b'1234')])
d4e26e
-    ent = topology_st.standalone.getEntry(last_user.dn, ldap.SCOPE_BASE,)
d4e26e
-    assert ent
d4e26e
-    assert ent.hasAttr(indexedAttr)
d4e26e
-    topology_st.standalone.modify_s(last_user.dn, [(ldap.MOD_DELETE, indexedAttr, None)])
d4e26e
-    ent = topology_st.standalone.getEntry(last_user.dn, ldap.SCOPE_BASE,)
d4e26e
-    assert ent
d4e26e
-    assert not ent.hasAttr(indexedAttr)
d4e26e
-
d4e26e
-    # Step 4
d4e26e
-    # The first component being not indexed the range on second is evaluated
d4e26e
-    try:
d4e26e
-        ents = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(&(sudoNotAfter=*)(%s>=111))' % indexedAttr)
d4e26e
-        assert len(ents) == 0
d4e26e
-    except ldap.SERVER_DOWN:
d4e26e
-        log.error('Likely testing against a debug version that asserted')
d4e26e
-        pass
d4e26e
-
d4e26e
-    # Step 5
d4e26e
-    assert not topology_st.standalone.searchErrorsLog('CRIT - list_candidates - NULL idl was recieved from filter_candidates_ext.')
d4e26e
-
d4e26e
-def audit_pattern_found(server, log_pattern):
d4e26e
-    file_obj = open(server.ds_paths.audit_log, "r")
d4e26e
-
d4e26e
-    found = None
d4e26e
-    # Use a while true iteration because 'for line in file: hit a
d4e26e
-    log.info('Audit log contains')
d4e26e
-    while True:
d4e26e
-        line = file_obj.readline()
d4e26e
-        log.info(line)
d4e26e
-        found = log_pattern.search(line)
d4e26e
-        if ((line == '') or (found)):
d4e26e
-            break
d4e26e
-
d4e26e
-    return found
d4e26e
-
d4e26e
-@pytest.mark.ds50026
d4e26e
-def test_ticketldbm_audit(topology_st):
d4e26e
-    """When updating LDBM config attributes, those attributes/values are not listed
d4e26e
-    in the audit log
d4e26e
-
d4e26e
-    :id: 5bf75c47-a283-430e-a65c-3c5fd8dbadb8
d4e26e
-    :setup: Standalone Instance
d4e26e
-    :steps:
d4e26e
-        1. Enable audit log
d4e26e
-        2. Update a set of config attrs in LDBM config
d4e26e
-        3. Disable audit log (to restore the default config)
d4e26e
-        4. Check that config attrs are listed in the audit log
d4e26e
-    :expectedresults:
d4e26e
-        1. Should succeeds
d4e26e
-        2. Should succeeds
d4e26e
-        3. Should succeeds
d4e26e
-        4. Should succeeds
d4e26e
-    """
d4e26e
-    inst = topology_st[0]
d4e26e
-
d4e26e
-    inst.config.enable_log('audit')
d4e26e
-
d4e26e
-    #inst.ds_paths.audit_log
d4e26e
-    attrs = ['nsslapd-lookthroughlimit', 'nsslapd-pagedidlistscanlimit', 'nsslapd-idlistscanlimit', 'nsslapd-db-locks']
d4e26e
-    mods = []
d4e26e
-    for attr in attrs:
d4e26e
-        mods.append((ldap.MOD_REPLACE, attr, b'10001'))
d4e26e
-    inst.modify_s(DN_CONFIG_LDBM, mods)
d4e26e
-    inst.config.enable_log('audit')
d4e26e
-
d4e26e
-    for attr in attrs:
d4e26e
-        log.info("Check %s is replaced in the audit log" % attr)
d4e26e
-        regex = re.compile("^replace: %s" % attr)
d4e26e
-        assert audit_pattern_found(inst, regex)
d4e26e
-
d4e26e
-
d4e26e
-if __name__ == '__main__':
d4e26e
-    # Run isolated
d4e26e
-    # -s for DEBUG mode
d4e26e
-    CURRENT_FILE = os.path.realpath(__file__)
d4e26e
-    pytest.main("-s %s" % CURRENT_FILE)
d4e26e
-
d4e26e
-
d4e26e
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_bind.c b/ldap/servers/slapd/back-ldbm/ldbm_bind.c
d4e26e
index fa450ecd5..38d115a32 100644
d4e26e
--- a/ldap/servers/slapd/back-ldbm/ldbm_bind.c
d4e26e
+++ b/ldap/servers/slapd/back-ldbm/ldbm_bind.c
d4e26e
@@ -76,8 +76,8 @@ ldbm_back_bind(Slapi_PBlock *pb)
d4e26e
     case LDAP_AUTH_SIMPLE: {
d4e26e
         Slapi_Value cv;
d4e26e
         if (slapi_entry_attr_find(e->ep_entry, "userpassword", &attr) != 0) {
d4e26e
-            slapi_send_ldap_result(pb, LDAP_INAPPROPRIATE_AUTH, NULL,
d4e26e
-                                   NULL, 0, NULL);
d4e26e
+            slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not have userpassword set");
d4e26e
+            slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL);
d4e26e
             CACHE_RETURN(&inst->inst_cache, &e);
d4e26e
             rc = SLAPI_BIND_FAIL;
d4e26e
             goto bail;
d4e26e
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
d4e26e
index b22c8e6b3..4337a0ed9 100644
d4e26e
--- a/ldap/servers/slapd/dse.c
d4e26e
+++ b/ldap/servers/slapd/dse.c
d4e26e
@@ -1431,7 +1431,8 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this
d4e26e
 
d4e26e
     ec = dse_get_entry_copy(pdse, sdn, DSE_USE_LOCK);
d4e26e
     if (ec == NULL) {
d4e26e
-        slapi_send_ldap_result(pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL);
d4e26e
+        slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not exist");
d4e26e
+        slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL);
d4e26e
         return (SLAPI_BIND_FAIL);
d4e26e
     }
d4e26e
 
d4e26e
@@ -1439,7 +1440,8 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this
d4e26e
     case LDAP_AUTH_SIMPLE: {
d4e26e
         Slapi_Value cv;
d4e26e
         if (slapi_entry_attr_find(ec, "userpassword", &attr) != 0) {
d4e26e
-            slapi_send_ldap_result(pb, LDAP_INAPPROPRIATE_AUTH, NULL, NULL, 0, NULL);
d4e26e
+            slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not have userpassword set");
d4e26e
+            slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL);
d4e26e
             slapi_entry_free(ec);
d4e26e
             return SLAPI_BIND_FAIL;
d4e26e
         }
d4e26e
@@ -1447,6 +1449,7 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this
d4e26e
 
d4e26e
         slapi_value_init_berval(&cv, cred);
d4e26e
         if (slapi_pw_find_sv(bvals, &cv) != 0) {
d4e26e
+            slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Invalid credentials");
d4e26e
             slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL);
d4e26e
             slapi_entry_free(ec);
d4e26e
             value_done(&cv;;
d4e26e
-- 
d4e26e
2.30.2
d4e26e