From 262e6aafb86c4e10f47bab593fcce840be1ee04a Mon Sep 17 00:00:00 2001 From: Akshay Adhikari Date: May 21 2018 09:22:34 +0000 Subject: Issue 49588 - Add py3 support for tickets : part-1 Description: Added py3 support by explicitly changing strings to bytes. Ported tests from ticket to test suites, also added docstrings. https://pagure.io/389-ds-base/issue/49588 Reviewed by: spichugi,vashirov (Thanks!) --- diff --git a/dirsrvtests/tests/suites/acl/enhanced_aci_modrnd_test.py b/dirsrvtests/tests/suites/acl/enhanced_aci_modrnd_test.py new file mode 100644 index 0000000..69290e9 --- /dev/null +++ b/dirsrvtests/tests/suites/acl/enhanced_aci_modrnd_test.py @@ -0,0 +1,121 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2016 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- +# +import pytest +from lib389.tasks import * +from lib389.utils import * +from lib389.topologies import topology_st + +logging.getLogger(__name__).setLevel(logging.DEBUG) +log = logging.getLogger(__name__) + +CONTAINER_1_OU = 'test_ou_1' +CONTAINER_2_OU = 'test_ou_2' +CONTAINER_1 = f'ou={CONTAINER_1_OU},dc=example,dc=com' +CONTAINER_2 = f'ou={CONTAINER_2_OU},dc=example,dc=com' +USER_CN = 'test_user' +USER_PWD = 'Secret123' +USER = f'cn={USER_CN},{CONTAINER_1}' + + +@pytest.fixture(scope="module") +def env_setup(topology_st): + """Adds two containers, one user and two ACI rules""" + + log.info("Add a container: %s" % CONTAINER_1) + topology_st.standalone.add_s(Entry((CONTAINER_1, + {'objectclass': 'top', + 'objectclass': 'organizationalunit', + 'ou': CONTAINER_1_OU, + }))) + + log.info("Add a container: %s" % CONTAINER_2) + topology_st.standalone.add_s(Entry((CONTAINER_2, + {'objectclass': 'top', + 'objectclass': 'organizationalunit', + 'ou': CONTAINER_2_OU, + }))) + + log.info("Add a user: %s" % USER) + topology_st.standalone.add_s(Entry((USER, + {'objectclass': 'top person'.split(), + 'cn': USER_CN, + 'sn': USER_CN, + 'userpassword': USER_PWD + }))) + + ACI_TARGET = '(targetattr="*")' + ACI_ALLOW = '(version 3.0; acl "All rights for %s"; allow (all) ' % USER + ACI_SUBJECT = 'userdn="ldap:///%s";)' % USER + ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT + mod = [(ldap.MOD_ADD, 'aci', ensure_bytes(ACI_BODY))] + + log.info("Add an ACI 'allow (all)' by %s to the %s" % (USER, + CONTAINER_1)) + topology_st.standalone.modify_s(CONTAINER_1, mod) + + log.info("Add an ACI 'allow (all)' by %s to the %s" % (USER, + CONTAINER_2)) + topology_st.standalone.modify_s(CONTAINER_2, mod) + + +@pytest.mark.ds47553 +def test_enhanced_aci_modrnd(topology_st, env_setup): + """Tests, that MODRDN operation is allowed, + if user has ACI right '(all)' under superior entries, + but doesn't have '(modrdn)' + + :id: 492cf2a9-2efe-4e3b-955e-85eca61d66b9 + :setup: Standalone instance + :steps: + 1. Create two containers + 2. Create a user within "ou=test_ou_1,dc=example,dc=com" + 3. Add an aci with a rule "cn=test_user is allowed all" within these containers + 4. Run MODRDN operation on the "cn=test_user" and set "newsuperior" to + the "ou=test_ou_2,dc=example,dc=com" + 5. Check there is no user under container one (ou=test_ou_1,dc=example,dc=com) + 6. Check there is a user under container two (ou=test_ou_2,dc=example,dc=com) + + :expectedresults: + 1. Two containers should be created + 2. User should be added successfully + 3. This should pass + 4. This should pass + 5. User should not be found under container ou=test_ou_1,dc=example,dc=com + 6. User should be found under container ou=test_ou_2,dc=example,dc=com + """ + + log.info("Bind as %s" % USER) + + topology_st.standalone.simple_bind_s(USER, USER_PWD) + + log.info("User MODRDN operation from %s to %s" % (CONTAINER_1, + CONTAINER_2)) + + topology_st.standalone.rename_s(USER, "cn=%s" % USER_CN, + newsuperior=CONTAINER_2, delold=1) + + log.info("Check there is no user in %s" % CONTAINER_1) + entries = topology_st.standalone.search_s(CONTAINER_1, + ldap.SCOPE_ONELEVEL, + 'cn=%s' % USER_CN) + assert not entries + + log.info("Check there is our user in %s" % CONTAINER_2) + entries = topology_st.standalone.search_s(CONTAINER_2, + ldap.SCOPE_ONELEVEL, + 'cn=%s' % USER_CN) + assert entries + + +if __name__ == '__main__': + # Run isolated + # -s for DEBUG mode + # -v for additional verbose + CURRENT_FILE = os.path.realpath(__file__) + pytest.main("-s -v %s" % CURRENT_FILE) diff --git a/dirsrvtests/tests/suites/filter/filter_test.py b/dirsrvtests/tests/suites/filter/filter_test.py index a2fb933..176b39a 100644 --- a/dirsrvtests/tests/suites/filter/filter_test.py +++ b/dirsrvtests/tests/suites/filter/filter_test.py @@ -11,11 +11,14 @@ import logging import pytest from lib389.tasks import * from lib389.topologies import topology_st -from lib389._constants import PASSWORD, DEFAULT_SUFFIX +from lib389._constants import PASSWORD, DEFAULT_SUFFIX, DN_DM, SUFFIX +from lib389.utils import * logging.getLogger(__name__).setLevel(logging.DEBUG) log = logging.getLogger(__name__) +ENTRY_NAME = 'test_entry' + def test_filter_escaped(topology_st): """Test we can search for an '*' in a attribute value. @@ -125,6 +128,100 @@ def test_filter_scope_one(topology_st): log.info('Search should only have one entry') assert len(results) == 1 +@pytest.mark.ds47313 +def test_filter_with_attribute_subtype(topology_st): + """Adds 2 test entries and Search with + filters including subtype and ! + + :id: 0e69f5f2-6a0a-480e-8282-fbcc50231908 + :setup: Standalone instance + :steps: + 1. Add 2 entries and create 3 filters + 2. Search for entry with filter: (&(cn=test_entry en only)(!(cn=test_entry fr))) + 3. Search for entry with filter: (&(cn=test_entry en only)(!(cn;fr=test_entry fr))) + 4. Search for entry with filter: (&(cn=test_entry en only)(!(cn;en=test_entry en))) + 5. Delete the added entries + :expectedresults: + 1. Operation should be successful + 2. Search should be successful + 3. Search should be successful + 4. Search should not be successful + 5. Delete the added entries + """ + + # bind as directory manager + topology_st.standalone.log.info("Bind as %s" % DN_DM) + topology_st.standalone.simple_bind_s(DN_DM, PASSWORD) + + # enable filter error logging + # mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '32')] + # topology_st.standalone.modify_s(DN_CONFIG, mod) + + topology_st.standalone.log.info("\n\n######################### ADD ######################\n") + + # Prepare the entry with cn;fr & cn;en + entry_name_fr = '%s fr' % (ENTRY_NAME) + entry_name_en = '%s en' % (ENTRY_NAME) + entry_name_both = '%s both' % (ENTRY_NAME) + entry_dn_both = 'cn=%s, %s' % (entry_name_both, SUFFIX) + entry_both = Entry(entry_dn_both) + entry_both.setValues('objectclass', 'top', 'person') + entry_both.setValues('sn', entry_name_both) + entry_both.setValues('cn', entry_name_both) + entry_both.setValues('cn;fr', entry_name_fr) + entry_both.setValues('cn;en', entry_name_en) + + # Prepare the entry with one member + entry_name_en_only = '%s en only' % (ENTRY_NAME) + entry_dn_en_only = 'cn=%s, %s' % (entry_name_en_only, SUFFIX) + entry_en_only = Entry(entry_dn_en_only) + entry_en_only.setValues('objectclass', 'top', 'person') + entry_en_only.setValues('sn', entry_name_en_only) + entry_en_only.setValues('cn', entry_name_en_only) + entry_en_only.setValues('cn;en', entry_name_en) + + topology_st.standalone.log.info("Try to add Add %s: %r" % (entry_dn_both, entry_both)) + topology_st.standalone.add_s(entry_both) + + topology_st.standalone.log.info("Try to add Add %s: %r" % (entry_dn_en_only, entry_en_only)) + topology_st.standalone.add_s(entry_en_only) + + topology_st.standalone.log.info("\n\n######################### SEARCH ######################\n") + + # filter: (&(cn=test_entry en only)(!(cn=test_entry fr))) + myfilter = '(&(sn=%s)(!(cn=%s)))' % (entry_name_en_only, entry_name_fr) + topology_st.standalone.log.info("Try to search with filter %s" % myfilter) + ents = topology_st.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, myfilter) + assert len(ents) == 1 + assert ensure_str(ents[0].sn) == entry_name_en_only + topology_st.standalone.log.info("Found %s" % ents[0].dn) + + # filter: (&(cn=test_entry en only)(!(cn;fr=test_entry fr))) + myfilter = '(&(sn=%s)(!(cn;fr=%s)))' % (entry_name_en_only, entry_name_fr) + topology_st.standalone.log.info("Try to search with filter %s" % myfilter) + ents = topology_st.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, myfilter) + assert len(ents) == 1 + assert ensure_str(ents[0].sn) == entry_name_en_only + topology_st.standalone.log.info("Found %s" % ents[0].dn) + + # filter: (&(cn=test_entry en only)(!(cn;en=test_entry en))) + myfilter = '(&(sn=%s)(!(cn;en=%s)))' % (entry_name_en_only, entry_name_en) + topology_st.standalone.log.info("Try to search with filter %s" % myfilter) + ents = topology_st.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, myfilter) + assert len(ents) == 0 + topology_st.standalone.log.info("Found none") + + topology_st.standalone.log.info("\n\n######################### DELETE ######################\n") + + topology_st.standalone.log.info("Try to delete %s " % entry_dn_both) + topology_st.standalone.delete_s(entry_dn_both) + + topology_st.standalone.log.info("Try to delete %s " % entry_dn_en_only) + topology_st.standalone.delete_s(entry_dn_en_only) + + log.info('Testcase PASSED') + + if __name__ == '__main__': # Run isolated # -s for DEBUG mode diff --git a/dirsrvtests/tests/suites/password/pwd_algo_test.py b/dirsrvtests/tests/suites/password/pwd_algo_test.py index e521727..ebc617e 100644 --- a/dirsrvtests/tests/suites/password/pwd_algo_test.py +++ b/dirsrvtests/tests/suites/password/pwd_algo_test.py @@ -13,6 +13,9 @@ from lib389.topologies import topology_st from lib389._constants import DEFAULT_SUFFIX, HOST_STANDALONE, DN_DM, PORT_STANDALONE from lib389.idm.user import UserAccounts +DEBUGGING = os.getenv('DEBUGGING', False) +USER_DN = 'uid=user,ou=People,%s' % DEFAULT_SUFFIX + logging.getLogger(__name__).setLevel(logging.INFO) log = logging.getLogger(__name__) @@ -65,6 +68,62 @@ def _test_algo(inst, algo_name): user.delete() # done! +def _test_bind_for_pbkdf2_algo(inst, password): + result = True + userconn = ldap.initialize("ldap://%s:%s" % (HOST_STANDALONE, PORT_STANDALONE)) + try: + userconn.simple_bind_s(USER_DN, password) + userconn.unbind_s() + except ldap.INVALID_CREDENTIALS: + result = False + return result + + +def _test_algo_for_pbkdf2(inst, algo_name): + inst.config.set('passwordStorageScheme', algo_name) + + if DEBUGGING: + print('Testing %s' % algo_name) + + # Create the user with a password + inst.add_s(Entry(( + USER_DN, { + 'objectClass': 'top account simplesecurityobject'.split(), + 'uid': 'user', + 'userpassword': ['Secret123', ] + }))) + + # Make sure when we read the userPassword field, it is the correct ALGO + pw_field = inst.search_s(USER_DN, ldap.SCOPE_BASE, '(objectClass=*)', ['userPassword'])[0] + + if DEBUGGING: + print(pw_field.getValue('userPassword')) + + if algo_name != 'CLEAR': + lalgo_name = algo_name.lower() + lpw_algo_name = pw_field.getValue('userPassword').lower() + assert (lpw_algo_name.startswith(ensure_bytes('{'+lalgo_name+'}'))) + # Now make sure a bind works + assert (_test_bind_for_pbkdf2_algo(inst, 'Secret123')) + # Bind with a wrong shorter password, should fail + assert (not _test_bind_for_pbkdf2_algo(inst, 'Wrong')) + # Bind with a wrong longer password, should fail + assert (not _test_bind_for_pbkdf2_algo(inst, 'This is even more wrong')) + # Bind with a password that has the algo in the name + assert (not _test_bind_for_pbkdf2_algo(inst, '{%s}SomeValues....' % algo_name)) + # Bind with a wrong exact length password. + assert (not _test_bind_for_pbkdf2_algo(inst, 'Alsowrong')) + # Bind with a subset password, should fail + assert (not _test_bind_for_pbkdf2_algo(inst, 'Secret')) + if algo_name != 'CRYPT': + # Bind with a subset password that is 1 char shorter, to detect off by 1 in clear + assert (not _test_bind_for_pbkdf2_algo(inst, 'Secret12')) + # Bind with a superset password, should fail + assert (not _test_bind_for_pbkdf2_algo(inst, 'Secret123456')) + # Delete the user + inst.delete_s(USER_DN) + # done! + @pytest.mark.parametrize("algo", ('CLEAR', 'CRYPT', 'CRYPT-MD5', 'CRYPT-SHA256', 'CRYPT-SHA512', 'MD5', 'SHA', 'SHA256', 'SHA384', 'SHA512', 'SMD5', 'SSHA', @@ -79,6 +138,37 @@ def test_pwd_algo_test(topology_st, algo): _test_algo(topology_st.standalone, algo) log.info('Test %s PASSED' % algo) +@pytest.mark.ds397 +def test_pbkdf2_algo(topology_st): + """Changing password storage scheme to PBKDF2_SHA256 + and trying to bind with different password combination + + :id: 112e265b-f468-4758-b8fa-ed8742de0182 + :setup: Standalone instance + :steps: + 1. Change password storage scheme to PBKDF2_SHA256 + 2. Add a test user entry + 3. Bind with correct password + 4. Bind with incorrect password combination(brute-force) + :expectedresults: + 1. Operation should be successful + 2. Operation should be successful + 3. Bind should be successful + 4. Should not allow to bind with incorrect password + """ + if DEBUGGING: + # Add debugging steps(if any)... + log.info("ATTACH NOW") + time.sleep(30) + + # Merge this to the password suite in the future + + for algo in ('PBKDF2_SHA256',): + for i in range(0, 10): + _test_algo_for_pbkdf2(topology_st.standalone, algo) + + log.info('Test PASSED') + if __name__ == '__main__': # Run isolated diff --git a/dirsrvtests/tests/suites/password/pwd_log_test.py b/dirsrvtests/tests/suites/password/pwd_log_test.py new file mode 100644 index 0000000..a113228 --- /dev/null +++ b/dirsrvtests/tests/suites/password/pwd_log_test.py @@ -0,0 +1,120 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2016 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- +# + +import logging + +import pytest +from lib389.tasks import * +from lib389.topologies import topology_st + +from lib389._constants import DN_CONFIG, DEFAULT_SUFFIX + +logging.getLogger(__name__).setLevel(logging.DEBUG) +log = logging.getLogger(__name__) + +@pytest.mark.ds365 +def test_hide_unhashed_pwd(topology_st): + """Change userPassword, enable hiding of un-hashed + password and check the audit logs. + + :id: c4a5d08d-f525-459b-82b9-3f68dae6fc71 + :setup: Standalone instance + :steps: + 1. Add a test user entry + 2. Set a new password for user and nsslapd-auditlog-logging-enabled to 'on' + 3. Disable nsslapd-auditlog-logging-hide-unhashed-pw + 4. Check the audit logs + 5. Set a new password for user and nsslapd-auditlog-logging-hide-unhashed-pw to 'on' + 6. Check the audit logs + :expectedresults: + 1. User addition should be successful + 2. New password should be set and audit logs should be enabled + 3. Operation should be successful + 4. Audit logs should show password without hash + 5. Operation should be successful + 6. Audit logs should hide password which is un-hashed + """ + + USER_DN = 'uid=test_entry,' + DEFAULT_SUFFIX + + # + # Add the test entry + # + topology_st.standalone.add_s(Entry((USER_DN, { + 'objectclass': 'top extensibleObject'.split(), + 'uid': 'test_entry', + 'userpassword': 'password' + }))) + + # + # Enable the audit log + # + topology_st.standalone.modify_s(DN_CONFIG, + [(ldap.MOD_REPLACE, + 'nsslapd-auditlog-logging-enabled', + b'on')]) + ''' + try: + ent = topology_st.standalone.getEntry(DN_CONFIG, attrlist=[ + 'nsslapd-instancedir', + 'nsslapd-errorlog', + 'nsslapd-accesslog', + 'nsslapd-certdir', + 'nsslapd-schemadir']) + ''' + # + # Allow the unhashed password to be written to audit log + # + topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, + 'nsslapd-auditlog-logging-hide-unhashed-pw', b'off')]) + + # + # Set new password, and check the audit log + # + topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE, + 'userpassword', + b'mypassword')]) + + # Check audit log + time.sleep(1) + if not topology_st.standalone.searchAuditLog('unhashed#user#password: mypassword'): + log.fatal('failed to find unhashed password in auditlog') + assert False + + # + # Hide unhashed password in audit log + # + topology_st.standalone.modify_s(DN_CONFIG, + [(ldap.MOD_REPLACE, + 'nsslapd-auditlog-logging-hide-unhashed-pw', + b'on')]) + log.info('Test complete') + + # + # Modify password, and check the audit log + # + topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE, + 'userpassword', + b'hidepassword')]) + + # Check audit log + time.sleep(1) + if topology_st.standalone.searchAuditLog('unhashed#user#password: hidepassword'): + log.fatal('Found unhashed password in auditlog') + assert False + + log.info('Test complete') + + +if __name__ == '__main__': + # Run isolated + # -s for DEBUG mode + CURRENT_FILE = os.path.realpath(__file__) + pytest.main("-s %s" % CURRENT_FILE) + diff --git a/dirsrvtests/tests/suites/plugins/pluginpath_validation_test.py b/dirsrvtests/tests/suites/plugins/pluginpath_validation_test.py new file mode 100644 index 0000000..1315fc6 --- /dev/null +++ b/dirsrvtests/tests/suites/plugins/pluginpath_validation_test.py @@ -0,0 +1,110 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2016 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- +# +import pytest +from lib389.tasks import * +from lib389.utils import * +from lib389.topologies import topology_st + +from lib389._constants import DEFAULT_SUFFIX, PLUGIN_WHOAMI + +logging.getLogger(__name__).setLevel(logging.DEBUG) +log = logging.getLogger(__name__) + + +@pytest.mark.ds47384 +def test_pluginpath_validation(topology_st): + '''Test pluginpath validation: relative and absolute paths + With the inclusion of ticket 47601 - we do allow plugin paths + outside the default location + + :id: 99f1fb2f-051d-4fd9-93d0-592dcd9b4c22 + :setup: Standalone instance + :steps: + 1. Copy the library to a temporary directory + 2. Add valid plugin paths + * using the absolute path to the current library + * using new remote location + 3. Set plugin path back to the default + 4. Check invalid path (no library present) + 5. Check invalid relative path (no library present) + + :expectedresults: + 1. This should pass + 2. This should pass + 3. This should pass + 4. This should fail + 5. This should fail + ''' + + if os.geteuid() != 0: + log.warn('This script must be run as root') + return + + os.system('setenforce 0') + + PLUGIN_DN = 'cn=%s,cn=plugins,cn=config' % PLUGIN_WHOAMI + tmp_dir = topology_st.standalone.get_tmp_dir() + plugin_dir = topology_st.standalone.get_plugin_dir() + + # Copy the library to our tmp directory + try: + shutil.copy('%s/libwhoami-plugin.so' % plugin_dir, tmp_dir) + except IOError as e: + log.fatal('Failed to copy %s/libwhoami-plugin.so to the tmp directory %s, error: %s' % ( + plugin_dir, tmp_dir, e.strerror)) + assert False + try: + shutil.copy('%s/libwhoami-plugin.la' % plugin_dir, tmp_dir) + except IOError as e: + log.warn('Failed to copy ' + plugin_dir + + '/libwhoami-plugin.la to the tmp directory, error: ' + + e.strerror) + + # + # Test adding valid plugin paths + # + # Try using the absolute path to the current library + topology_st.standalone.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, + 'nsslapd-pluginPath', ensure_bytes('%s/libwhoami-plugin' % plugin_dir))]) + + # Try using new remote location + topology_st.standalone.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, + 'nsslapd-pluginPath', ensure_bytes('%s/libwhoami-plugin' % tmp_dir))]) + + # Set plugin path back to the default + topology_st.standalone.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, + 'nsslapd-pluginPath', b'libwhoami-plugin')]) + + # + # Test invalid path (no library present) + # + with pytest.raises(ldap.UNWILLING_TO_PERFORM): + topology_st.standalone.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, + 'nsslapd-pluginPath', b'/bin/libwhoami-plugin')]) + # No exception?! This is an error + log.error('Invalid plugin path was incorrectly accepted by the server!') + + # + # Test invalid relative path (no library present) + # + with pytest.raises(ldap.UNWILLING_TO_PERFORM): + topology_st.standalone.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, + 'nsslapd-pluginPath', b'../libwhoami-plugin')]) + # No exception?! This is an error + log.error('Invalid plugin path was incorrectly accepted by the server!') + + log.info('Test complete') + + +if __name__ == '__main__': + # Run isolated + # -s for DEBUG mode + CURRENT_FILE = os.path.realpath(__file__) + pytest.main("-s %s" % CURRENT_FILE) + diff --git a/dirsrvtests/tests/tickets/ticket365_test.py b/dirsrvtests/tests/tickets/ticket365_test.py deleted file mode 100644 index 505a597..0000000 --- a/dirsrvtests/tests/tickets/ticket365_test.py +++ /dev/null @@ -1,138 +0,0 @@ -# --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2016 Red Hat, Inc. -# All rights reserved. -# -# License: GPL (version 3 or any later version). -# See LICENSE for details. -# --- END COPYRIGHT BLOCK --- -# - -import logging - -import pytest -from lib389.tasks import * -from lib389.topologies import topology_st - -from lib389._constants import DN_CONFIG, DEFAULT_SUFFIX - -logging.getLogger(__name__).setLevel(logging.DEBUG) -log = logging.getLogger(__name__) - - -def test_ticket365(topology_st): - ''' - Write your testcase here... - - nsslapd-auditlog-logging-hide-unhashed-pw - - and test - - nsslapd-unhashed-pw-switch ticket 561 - - on, off, nolog? - ''' - - USER_DN = 'uid=test_entry,' + DEFAULT_SUFFIX - - # - # Add the test entry - # - try: - topology_st.standalone.add_s(Entry((USER_DN, { - 'objectclass': 'top extensibleObject'.split(), - 'uid': 'test_entry', - 'userpassword': 'password' - }))) - except ldap.LDAPError as e: - log.error('Failed to add test user: error ' + e.message['desc']) - assert False - - # - # Enable the audit log - # - try: - topology_st.standalone.modify_s(DN_CONFIG, - [(ldap.MOD_REPLACE, - 'nsslapd-auditlog-logging-enabled', - 'on')]) - except ldap.LDAPError as e: - log.fatal('Failed to enable audit log, error: ' + e.message['desc']) - assert False - ''' - try: - ent = topology_st.standalone.getEntry(DN_CONFIG, attrlist=[ - 'nsslapd-instancedir', - 'nsslapd-errorlog', - 'nsslapd-accesslog', - 'nsslapd-certdir', - 'nsslapd-schemadir']) - ''' - # - # Allow the unhashed password to be written to audit log - # - try: - topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, - 'nsslapd-auditlog-logging-hide-unhashed-pw', 'off')]) - except ldap.LDAPError as e: - log.fatal('Failed to enable writing unhashed password to audit log, ' + - 'error: ' + e.message['desc']) - assert False - - # - # Set new password, and check the audit log - # - try: - topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE, - 'userpassword', - 'mypassword')]) - except ldap.LDAPError as e: - log.fatal('Failed to enable writing unhashed password to audit log, ' + - 'error: ' + e.message['desc']) - assert False - - # Check audit log - time.sleep(1) - if not topology_st.standalone.searchAuditLog('unhashed#user#password: mypassword'): - log.fatal('failed to find unhashed password in auditlog') - assert False - - # - # Hide unhashed password in audit log - # - try: - topology_st.standalone.modify_s(DN_CONFIG, - [(ldap.MOD_REPLACE, - 'nsslapd-auditlog-logging-hide-unhashed-pw', - 'on')]) - except ldap.LDAPError as e: - log.fatal('Failed to deny writing unhashed password to audit log, ' + - 'error: ' + e.message['desc']) - assert False - log.info('Test complete') - - # - # Modify password, and check the audit log - # - try: - topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE, - 'userpassword', - 'hidepassword')]) - except ldap.LDAPError as e: - log.fatal('Failed to enable writing unhashed password to audit log, ' + - 'error: ' + e.message['desc']) - assert False - - # Check audit log - time.sleep(1) - if topology_st.standalone.searchAuditLog('unhashed#user#password: hidepassword'): - log.fatal('Found unhashed password in auditlog') - assert False - - log.info('Test complete') - - -if __name__ == '__main__': - # Run isolated - # -s for DEBUG mode - CURRENT_FILE = os.path.realpath(__file__) - pytest.main("-s %s" % CURRENT_FILE) diff --git a/dirsrvtests/tests/tickets/ticket397_test.py b/dirsrvtests/tests/tickets/ticket397_test.py deleted file mode 100644 index bd6cb8c..0000000 --- a/dirsrvtests/tests/tickets/ticket397_test.py +++ /dev/null @@ -1,103 +0,0 @@ -import pytest -from lib389.tasks import * -from lib389.utils import * -from lib389.topologies import topology_st - -from lib389._constants import DEFAULT_SUFFIX, HOST_STANDALONE, PORT_STANDALONE - -DEBUGGING = os.getenv('DEBUGGING', False) -USER_DN = 'uid=user,ou=People,%s' % DEFAULT_SUFFIX - -if DEBUGGING: - logging.getLogger(__name__).setLevel(logging.DEBUG) -else: - logging.getLogger(__name__).setLevel(logging.INFO) - -# Skip on older versions -pytestmark = pytest.mark.skipif(ds_is_older('1.3.6'), reason="Not implemented") - -log = logging.getLogger(__name__) - - -def _test_bind(inst, password): - result = True - userconn = ldap.initialize("ldap://%s:%s" % (HOST_STANDALONE, PORT_STANDALONE)) - try: - userconn.simple_bind_s(USER_DN, password) - userconn.unbind_s() - except ldap.INVALID_CREDENTIALS: - result = False - return result - - -def _test_algo(inst, algo_name): - inst.config.set('passwordStorageScheme', algo_name) - - if DEBUGGING: - print('Testing %s' % algo_name) - - # Create the user with a password - inst.add_s(Entry(( - USER_DN, { - 'objectClass': 'top account simplesecurityobject'.split(), - 'uid': 'user', - 'userpassword': ['Secret123', ] - }))) - - # Make sure when we read the userPassword field, it is the correct ALGO - pw_field = inst.search_s(USER_DN, ldap.SCOPE_BASE, '(objectClass=*)', ['userPassword'])[0] - - if DEBUGGING: - print(pw_field.getValue('userPassword')) - - if algo_name != 'CLEAR': - lalgo_name = algo_name.lower() - lpw_algo_name = pw_field.getValue('userPassword').lower() - assert (lpw_algo_name.startswith("{%s}" % lalgo_name)) - # Now make sure a bind works - assert (_test_bind(inst, 'Secret123')) - # Bind with a wrong shorter password, should fail - assert (not _test_bind(inst, 'Wrong')) - # Bind with a wrong longer password, should fail - assert (not _test_bind(inst, 'This is even more wrong')) - # Bind with a password that has the algo in the name - assert (not _test_bind(inst, '{%s}SomeValues....' % algo_name)) - # Bind with a wrong exact length password. - assert (not _test_bind(inst, 'Alsowrong')) - # Bind with a subset password, should fail - assert (not _test_bind(inst, 'Secret')) - if algo_name != 'CRYPT': - # Bind with a subset password that is 1 char shorter, to detect off by 1 in clear - assert (not _test_bind(inst, 'Secret12')) - # Bind with a superset password, should fail - assert (not _test_bind(inst, 'Secret123456')) - # Delete the user - inst.delete_s(USER_DN) - # done! - - -def test_397(topology_st): - """ - Assert that all of our password algorithms correctly PASS and FAIL varying - password conditions. - - """ - if DEBUGGING: - # Add debugging steps(if any)... - log.info("ATTACH NOW") - time.sleep(30) - - # Merge this to the password suite in the future - - for algo in ('PBKDF2_SHA256',): - for i in range(0, 10): - _test_algo(topology_st.standalone, algo) - - log.info('Test PASSED') - - -if __name__ == '__main__': - # Run isolated - # -s for DEBUG mode - CURRENT_FILE = os.path.realpath(__file__) - pytest.main("-s %s" % CURRENT_FILE) diff --git a/dirsrvtests/tests/tickets/ticket47313_test.py b/dirsrvtests/tests/tickets/ticket47313_test.py deleted file mode 100644 index 8640f40..0000000 --- a/dirsrvtests/tests/tickets/ticket47313_test.py +++ /dev/null @@ -1,106 +0,0 @@ -# --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2016 Red Hat, Inc. -# All rights reserved. -# -# License: GPL (version 3 or any later version). -# See LICENSE for details. -# --- END COPYRIGHT BLOCK --- -# -import logging - -import ldap -import pytest -from lib389 import Entry -from lib389._constants import * -from lib389.topologies import topology_st - -log = logging.getLogger(__name__) - -ENTRY_NAME = 'test_entry' - - -def test_ticket47313_run(topology_st): - """ - It adds 2 test entries - Search with filters including subtype and ! - It deletes the added entries - """ - - # bind as directory manager - topology_st.standalone.log.info("Bind as %s" % DN_DM) - topology_st.standalone.simple_bind_s(DN_DM, PASSWORD) - - # enable filter error logging - # mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '32')] - # topology_st.standalone.modify_s(DN_CONFIG, mod) - - topology_st.standalone.log.info("\n\n######################### ADD ######################\n") - - # Prepare the entry with cn;fr & cn;en - entry_name_fr = '%s fr' % (ENTRY_NAME) - entry_name_en = '%s en' % (ENTRY_NAME) - entry_name_both = '%s both' % (ENTRY_NAME) - entry_dn_both = 'cn=%s, %s' % (entry_name_both, SUFFIX) - entry_both = Entry(entry_dn_both) - entry_both.setValues('objectclass', 'top', 'person') - entry_both.setValues('sn', entry_name_both) - entry_both.setValues('cn', entry_name_both) - entry_both.setValues('cn;fr', entry_name_fr) - entry_both.setValues('cn;en', entry_name_en) - - # Prepare the entry with one member - entry_name_en_only = '%s en only' % (ENTRY_NAME) - entry_dn_en_only = 'cn=%s, %s' % (entry_name_en_only, SUFFIX) - entry_en_only = Entry(entry_dn_en_only) - entry_en_only.setValues('objectclass', 'top', 'person') - entry_en_only.setValues('sn', entry_name_en_only) - entry_en_only.setValues('cn', entry_name_en_only) - entry_en_only.setValues('cn;en', entry_name_en) - - topology_st.standalone.log.info("Try to add Add %s: %r" % (entry_dn_both, entry_both)) - topology_st.standalone.add_s(entry_both) - - topology_st.standalone.log.info("Try to add Add %s: %r" % (entry_dn_en_only, entry_en_only)) - topology_st.standalone.add_s(entry_en_only) - - topology_st.standalone.log.info("\n\n######################### SEARCH ######################\n") - - # filter: (&(cn=test_entry en only)(!(cn=test_entry fr))) - myfilter = '(&(sn=%s)(!(cn=%s)))' % (entry_name_en_only, entry_name_fr) - topology_st.standalone.log.info("Try to search with filter %s" % myfilter) - ents = topology_st.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, myfilter) - assert len(ents) == 1 - assert ents[0].sn == entry_name_en_only - topology_st.standalone.log.info("Found %s" % ents[0].dn) - - # filter: (&(cn=test_entry en only)(!(cn;fr=test_entry fr))) - myfilter = '(&(sn=%s)(!(cn;fr=%s)))' % (entry_name_en_only, entry_name_fr) - topology_st.standalone.log.info("Try to search with filter %s" % myfilter) - ents = topology_st.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, myfilter) - assert len(ents) == 1 - assert ents[0].sn == entry_name_en_only - topology_st.standalone.log.info("Found %s" % ents[0].dn) - - # filter: (&(cn=test_entry en only)(!(cn;en=test_entry en))) - myfilter = '(&(sn=%s)(!(cn;en=%s)))' % (entry_name_en_only, entry_name_en) - topology_st.standalone.log.info("Try to search with filter %s" % myfilter) - ents = topology_st.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, myfilter) - assert len(ents) == 0 - topology_st.standalone.log.info("Found none") - - topology_st.standalone.log.info("\n\n######################### DELETE ######################\n") - - topology_st.standalone.log.info("Try to delete %s " % entry_dn_both) - topology_st.standalone.delete_s(entry_dn_both) - - topology_st.standalone.log.info("Try to delete %s " % entry_dn_en_only) - topology_st.standalone.delete_s(entry_dn_en_only) - - log.info('Testcase PASSED') - - -if __name__ == '__main__': - # Run isolated - # -s for DEBUG mode - CURRENT_FILE = os.path.realpath(__file__) - pytest.main("-s %s" % CURRENT_FILE) diff --git a/dirsrvtests/tests/tickets/ticket47384_test.py b/dirsrvtests/tests/tickets/ticket47384_test.py deleted file mode 100644 index da01b3d..0000000 --- a/dirsrvtests/tests/tickets/ticket47384_test.py +++ /dev/null @@ -1,121 +0,0 @@ -# --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2016 Red Hat, Inc. -# All rights reserved. -# -# License: GPL (version 3 or any later version). -# See LICENSE for details. -# --- END COPYRIGHT BLOCK --- -# -import pytest -from lib389.tasks import * -from lib389.utils import * -from lib389.topologies import topology_st - -from lib389._constants import DEFAULT_SUFFIX, PLUGIN_WHOAMI - -logging.getLogger(__name__).setLevel(logging.DEBUG) -log = logging.getLogger(__name__) - - -def test_ticket47384(topology_st): - ''' - Test pluginpath validation: relative and absolute paths - - With the inclusion of ticket 47601 - we do allow plugin paths - outside the default location - ''' - - if os.geteuid() != 0: - log.warn('This script must be run as root') - return - - os.system('setenforce 0') - - PLUGIN_DN = 'cn=%s,cn=plugins,cn=config' % PLUGIN_WHOAMI - tmp_dir = topology_st.standalone.get_tmp_dir() - plugin_dir = topology_st.standalone.get_plugin_dir() - - # Copy the library to our tmp directory - try: - shutil.copy('%s/libwhoami-plugin.so' % plugin_dir, tmp_dir) - except IOError as e: - log.fatal('Failed to copy %s/libwhoami-plugin.so to the tmp directory %s, error: %s' % ( - plugin_dir, tmp_dir, e.strerror)) - assert False - try: - shutil.copy('%s/libwhoami-plugin.la' % plugin_dir, tmp_dir) - except IOError as e: - log.warn('Failed to copy ' + plugin_dir + - '/libwhoami-plugin.la to the tmp directory, error: ' - + e.strerror) - - # - # Test adding valid plugin paths - # - # Try using the absolute path to the current library - try: - topology_st.standalone.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, - 'nsslapd-pluginPath', '%s/libwhoami-plugin' % plugin_dir)]) - except ldap.LDAPError as e: - log.error('Failed to set valid plugin path (%s): error (%s)' % - ('%s/libwhoami-plugin' % plugin_dir, e.message['desc'])) - assert False - - # Try using new remote location - try: - topology_st.standalone.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, - 'nsslapd-pluginPath', '%s/libwhoami-plugin' % tmp_dir)]) - except ldap.LDAPError as e: - log.error('Failed to set valid plugin path (%s): error (%s)' % - ('%s/libwhoami-plugin' % tmp_dir, e.message['desc'])) - assert False - - # Set plugin path back to the default - try: - topology_st.standalone.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, - 'nsslapd-pluginPath', 'libwhoami-plugin')]) - except ldap.LDAPError as e: - log.error('Failed to set valid relative plugin path (%s): error (%s)' % - ('libwhoami-plugin' % tmp_dir, e.message['desc'])) - assert False - - # - # Test invalid path (no library present) - # - try: - topology_st.standalone.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, - 'nsslapd-pluginPath', '/bin/libwhoami-plugin')]) - # No exception?! This is an error - log.error('Invalid plugin path was incorrectly accepted by the server!') - assert False - except ldap.UNWILLING_TO_PERFORM: - # Correct, operation should be rejected - pass - except ldap.LDAPError as e: - log.error('Failed to set invalid plugin path (%s): error (%s)' % - ('/bin/libwhoami-plugin', e.message['desc'])) - - # - # Test invalid relative path (no library present) - # - try: - topology_st.standalone.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, - 'nsslapd-pluginPath', '../libwhoami-plugin')]) - # No exception?! This is an error - log.error('Invalid plugin path was incorrectly accepted by the server!') - assert False - except ldap.UNWILLING_TO_PERFORM: - # Correct, operation should be rejected - pass - except ldap.LDAPError as e: - log.error('Failed to set invalid plugin path (%s): error (%s)' % - ('../libwhoami-plugin', e.message['desc'])) - - log.info('Test complete') - - -if __name__ == '__main__': - # Run isolated - # -s for DEBUG mode - CURRENT_FILE = os.path.realpath(__file__) - pytest.main("-s %s" % CURRENT_FILE) diff --git a/dirsrvtests/tests/tickets/ticket47553_test.py b/dirsrvtests/tests/tickets/ticket47553_test.py deleted file mode 100644 index 08454d4..0000000 --- a/dirsrvtests/tests/tickets/ticket47553_test.py +++ /dev/null @@ -1,119 +0,0 @@ -# --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2016 Red Hat, Inc. -# All rights reserved. -# -# License: GPL (version 3 or any later version). -# See LICENSE for details. -# --- END COPYRIGHT BLOCK --- -# -import pytest -from lib389.tasks import * -from lib389.utils import * -from lib389.topologies import topology_st - -logging.getLogger(__name__).setLevel(logging.DEBUG) -log = logging.getLogger(__name__) - -CONTAINER_1_OU = 'test_ou_1' -CONTAINER_2_OU = 'test_ou_2' -CONTAINER_1 = 'ou=%s,dc=example,dc=com' % CONTAINER_1_OU -CONTAINER_2 = 'ou=%s,dc=example,dc=com' % CONTAINER_2_OU -USER_CN = 'test_user' -USER_PWD = 'Secret123' -USER = 'cn=%s,%s' % (USER_CN, CONTAINER_1) - - -@pytest.fixture(scope="module") -def env_setup(topology_st): - """Adds two containers, one user and two ACI rules""" - - try: - log.info("Add a container: %s" % CONTAINER_1) - topology_st.standalone.add_s(Entry((CONTAINER_1, - {'objectclass': 'top', - 'objectclass': 'organizationalunit', - 'ou': CONTAINER_1_OU, - }))) - - log.info("Add a container: %s" % CONTAINER_2) - topology_st.standalone.add_s(Entry((CONTAINER_2, - {'objectclass': 'top', - 'objectclass': 'organizationalunit', - 'ou': CONTAINER_2_OU, - }))) - - log.info("Add a user: %s" % USER) - topology_st.standalone.add_s(Entry((USER, - {'objectclass': 'top person'.split(), - 'cn': USER_CN, - 'sn': USER_CN, - 'userpassword': USER_PWD - }))) - except ldap.LDAPError as e: - log.error('Failed to add object to database: %s' % e.message['desc']) - assert False - - ACI_TARGET = '(targetattr="*")' - ACI_ALLOW = '(version 3.0; acl "All rights for %s"; allow (all) ' % USER - ACI_SUBJECT = 'userdn="ldap:///%s";)' % USER - ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT - mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)] - - try: - log.info("Add an ACI 'allow (all)' by %s to the %s" % (USER, - CONTAINER_1)) - topology_st.standalone.modify_s(CONTAINER_1, mod) - - log.info("Add an ACI 'allow (all)' by %s to the %s" % (USER, - CONTAINER_2)) - topology_st.standalone.modify_s(CONTAINER_2, mod) - except ldap.LDAPError as e: - log.fatal('Failed to add ACI: error (%s)' % (e.message['desc'])) - assert False - - -def test_ticket47553(topology_st, env_setup): - """Tests, that MODRDN operation is allowed, - if user has ACI right '(all)' under superior entries, - but doesn't have '(modrdn)' - """ - - log.info("Bind as %s" % USER) - try: - topology_st.standalone.simple_bind_s(USER, USER_PWD) - except ldap.LDAPError as e: - log.error('Bind failed for %s, error %s' % (USER, e.message['desc'])) - assert False - - log.info("User MODRDN operation from %s to %s" % (CONTAINER_1, - CONTAINER_2)) - try: - topology_st.standalone.rename_s(USER, "cn=%s" % USER_CN, - newsuperior=CONTAINER_2, delold=1) - except ldap.LDAPError as e: - log.error('MODRDN failed for %s, error %s' % (USER, e.message['desc'])) - assert False - - try: - log.info("Check there is no user in %s" % CONTAINER_1) - entries = topology_st.standalone.search_s(CONTAINER_1, - ldap.SCOPE_ONELEVEL, - 'cn=%s' % USER_CN) - assert not entries - - log.info("Check there is our user in %s" % CONTAINER_2) - entries = topology_st.standalone.search_s(CONTAINER_2, - ldap.SCOPE_ONELEVEL, - 'cn=%s' % USER_CN) - assert entries - except ldap.LDAPError as e: - log.fatal('Search failed, error: ' + e.message['desc']) - assert False - - -if __name__ == '__main__': - # Run isolated - # -s for DEBUG mode - # -v for additional verbose - CURRENT_FILE = os.path.realpath(__file__) - pytest.main("-s -v %s" % CURRENT_FILE)