|
|
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 |
|