From 0f309fee0e2b337ee333d9ce80a6c64d6f7161ef Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Thu, 12 Nov 2020 17:53:09 +0100 Subject: [PATCH] Backport tests from master branch, fix failing tests (#4425) Relates: #2820 Reviewed by: mreynolds (Thanks!) --- dirsrvtests/tests/suites/acl/acivattr_test.py | 50 +-- dirsrvtests/tests/suites/acl/acl_deny_test.py | 10 +- dirsrvtests/tests/suites/acl/acl_test.py | 26 +- .../acl/default_aci_allows_self_write.py | 4 +- dirsrvtests/tests/suites/acl/deladd_test.py | 54 ++-- .../suites/acl/enhanced_aci_modrnd_test.py | 22 +- .../suites/acl/globalgroup_part2_test.py | 36 ++- .../tests/suites/acl/globalgroup_test.py | 16 +- .../tests/suites/acl/keywords_part2_test.py | 30 +- dirsrvtests/tests/suites/acl/keywords_test.py | 71 ++--- dirsrvtests/tests/suites/acl/misc_test.py | 104 +++--- dirsrvtests/tests/suites/acl/modrdn_test.py | 180 +++++------ dirsrvtests/tests/suites/acl/roledn_test.py | 4 +- .../suites/acl/selfdn_permissions_test.py | 23 +- dirsrvtests/tests/suites/acl/syntax_test.py | 56 ++-- dirsrvtests/tests/suites/acl/userattr_test.py | 6 +- .../tests/suites/acl/valueacl_part2_test.py | 107 ++++--- dirsrvtests/tests/suites/acl/valueacl_test.py | 207 ++++++------ dirsrvtests/tests/suites/basic/basic_test.py | 23 +- .../tests/suites/ds_logs/ds_logs_test.py | 301 ++++++++++++++---- .../filter/rfc3673_all_oper_attrs_test.py | 23 +- .../suites/mapping_tree/acceptance_test.py | 65 ++++ .../be_del_and_default_naming_attr_test.py | 17 +- .../password/pwdPolicy_attribute_test.py | 9 +- .../suites/replication/changelog_test.py | 6 +- .../replication/conflict_resolve_test.py | 4 +- .../tests/suites/replication/rfc2307compat.py | 174 ++++++++++ dirsrvtests/tests/suites/roles/__init__.py | 3 + dirsrvtests/tests/suites/roles/basic_test.py | 83 ++--- .../tests/suites/sasl/regression_test.py | 21 +- .../tests/suites/syncrepl_plugin/__init__.py | 163 ++++++++++ .../suites/syncrepl_plugin/basic_test.py | 66 ++-- .../tests/suites/vlv/regression_test.py | 2 +- 33 files changed, 1319 insertions(+), 647 deletions(-) create mode 100644 dirsrvtests/tests/suites/mapping_tree/acceptance_test.py create mode 100644 dirsrvtests/tests/suites/replication/rfc2307compat.py create mode 100644 dirsrvtests/tests/suites/roles/__init__.py create mode 100644 dirsrvtests/tests/suites/syncrepl_plugin/__init__.py diff --git a/dirsrvtests/tests/suites/acl/acivattr_test.py b/dirsrvtests/tests/suites/acl/acivattr_test.py index 35759f36e..d55eea023 100644 --- a/dirsrvtests/tests/suites/acl/acivattr_test.py +++ b/dirsrvtests/tests/suites/acl/acivattr_test.py @@ -174,18 +174,19 @@ LDAPURL_ACI = '(targetattr="*")(version 3.0; acl "url"; allow (all) userdn="ldap '(ENG_USER, ENG_MANAGER, LDAPURL_ACI)', ]) def test_positive(topo, _add_user, aci_of_user, user, entry, aci): - """ - :id: ba6d5e9c-786b-11e8-860d-8c16451d917b - :parametrized: yes - :setup: server - :steps: - 1. Add test entry - 2. Add ACI - 3. ACI role should be followed - :expectedresults: - 1. Entry should be added - 2. Operation should succeed - 3. Operation should succeed + """Positive testing of ACLs + + :id: ba6d5e9c-786b-11e8-860d-8c16451d917b + :parametrized: yes + :setup: server + :steps: + 1. Add test entry + 2. Add ACI + 3. ACI role should be followed + :expectedresults: + 1. Entry should be added + 2. Operation should succeed + 3. Operation should succeed """ # set aci Domain(topo.standalone, DNBASE).set("aci", aci) @@ -225,18 +226,19 @@ def test_positive(topo, _add_user, aci_of_user, user, entry, aci): ]) def test_negative(topo, _add_user, aci_of_user, user, entry, aci): - """ - :id: c4c887c2-786b-11e8-a328-8c16451d917b - :parametrized: yes - :setup: server - :steps: - 1. Add test entry - 2. Add ACI - 3. ACI role should be followed - :expectedresults: - 1. Entry should be added - 2. Operation should succeed - 3. Operation should succeed + """Negative testing of ACLs + + :id: c4c887c2-786b-11e8-a328-8c16451d917b + :parametrized: yes + :setup: server + :steps: + 1. Add test entry + 2. Add ACI + 3. ACI role should be followed + :expectedresults: + 1. Entry should be added + 2. Operation should succeed + 3. Operation should not succeed """ # set aci Domain(topo.standalone, DNBASE).set("aci", aci) diff --git a/dirsrvtests/tests/suites/acl/acl_deny_test.py b/dirsrvtests/tests/suites/acl/acl_deny_test.py index 8ea6cd27b..96d08e9da 100644 --- a/dirsrvtests/tests/suites/acl/acl_deny_test.py +++ b/dirsrvtests/tests/suites/acl/acl_deny_test.py @@ -1,3 +1,11 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2020 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 import os @@ -5,7 +13,7 @@ import ldap import time from lib389._constants import * from lib389.topologies import topology_st as topo -from lib389.idm.user import UserAccount, UserAccounts, TEST_USER_PROPERTIES +from lib389.idm.user import UserAccount, TEST_USER_PROPERTIES from lib389.idm.domain import Domain pytestmark = pytest.mark.tier1 diff --git a/dirsrvtests/tests/suites/acl/acl_test.py b/dirsrvtests/tests/suites/acl/acl_test.py index 5ca86523c..4c3214650 100644 --- a/dirsrvtests/tests/suites/acl/acl_test.py +++ b/dirsrvtests/tests/suites/acl/acl_test.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2016 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -14,9 +14,8 @@ from lib389.schema import Schema from lib389.idm.domain import Domain from lib389.idm.user import UserAccount, UserAccounts, TEST_USER_PROPERTIES from lib389.idm.organizationalrole import OrganizationalRole, OrganizationalRoles - from lib389.topologies import topology_m2 -from lib389._constants import SUFFIX, DN_SCHEMA, DN_DM, DEFAULT_SUFFIX, PASSWORD +from lib389._constants import SUFFIX, DN_DM, DEFAULT_SUFFIX, PASSWORD pytestmark = pytest.mark.tier1 @@ -243,6 +242,14 @@ def moddn_setup(topology_m2): 'userpassword': BIND_PW}) user.create(properties=user_props, basedn=SUFFIX) + # Add anonymous read aci + ACI_TARGET = "(target = \"ldap:///%s\")(targetattr=\"*\")" % (SUFFIX) + ACI_ALLOW = "(version 3.0; acl \"Anonymous Read access\"; allow (read,search,compare)" + ACI_SUBJECT = " userdn = \"ldap:///anyone\";)" + ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT + suffix = Domain(m1, SUFFIX) + suffix.add('aci', ACI_BODY) + # DIT for staging m1.log.info("Add {}".format(STAGING_DN)) o_roles.create(properties={'cn': STAGING_CN, 'description': "staging DIT"}) @@ -411,7 +418,8 @@ def test_moddn_staging_prod(topology_m2, moddn_setup, def test_moddn_staging_prod_9(topology_m2, moddn_setup): - """ + """Test with nsslapd-moddn-aci set to off so that MODDN requires an 'add' aci. + :id: 222dd7e8-7ff1-40b8-ad26-6f8e42fbfcd9 :setup: MMR with two masters, M1 - staging DIT @@ -1061,10 +1069,12 @@ def test_mode_legacy_ger_with_moddn(topology_m2, moddn_setup): @pytest.fixture(scope="module") def rdn_write_setup(topology_m2): topology_m2.ms["master1"].log.info("\n\n######## Add entry tuser ########\n") - topology_m2.ms["master1"].add_s(Entry((SRC_ENTRY_DN, { - 'objectclass': "top person".split(), - 'sn': SRC_ENTRY_CN, - 'cn': SRC_ENTRY_CN}))) + user = UserAccount(topology_m2.ms["master1"], SRC_ENTRY_DN) + user_props = TEST_USER_PROPERTIES.copy() + user_props.update({'sn': SRC_ENTRY_CN, + 'cn': SRC_ENTRY_CN, + 'userpassword': BIND_PW}) + user.create(properties=user_props, basedn=SUFFIX) def test_rdn_write_get_ger(topology_m2, rdn_write_setup): diff --git a/dirsrvtests/tests/suites/acl/default_aci_allows_self_write.py b/dirsrvtests/tests/suites/acl/default_aci_allows_self_write.py index 5700abfba..9c7226b42 100644 --- a/dirsrvtests/tests/suites/acl/default_aci_allows_self_write.py +++ b/dirsrvtests/tests/suites/acl/default_aci_allows_self_write.py @@ -21,7 +21,7 @@ pytestmark = pytest.mark.tier1 USER_PASSWORD = "some test password" NEW_USER_PASSWORD = "some new password" -@pytest.mark.skipif(default_paths.perl_enabled or ds_is_older('1.4.2.0'), reason="Default aci's in older versions do not support this functionality") +@pytest.mark.skipif(ds_is_older('1.4.2.0'), reason="Default aci's in older versions do not support this functionality") def test_acl_default_allow_self_write_nsuser(topology): """ Testing nsusers can self write and self read. This it a sanity test @@ -80,7 +80,7 @@ def test_acl_default_allow_self_write_nsuser(topology): self_ent.change_password(USER_PASSWORD, NEW_USER_PASSWORD) -@pytest.mark.skipif(default_paths.perl_enabled or ds_is_older('1.4.2.0'), reason="Default aci's in older versions do not support this functionality") +@pytest.mark.skipif(ds_is_older('1.4.2.0'), reason="Default aci's in older versions do not support this functionality") def test_acl_default_allow_self_write_user(topology): """ Testing users can self write and self read. This it a sanity test diff --git a/dirsrvtests/tests/suites/acl/deladd_test.py b/dirsrvtests/tests/suites/acl/deladd_test.py index 45a66be94..afdc772d1 100644 --- a/dirsrvtests/tests/suites/acl/deladd_test.py +++ b/dirsrvtests/tests/suites/acl/deladd_test.py @@ -86,8 +86,8 @@ def _add_user(request, topo): def test_allow_delete_access_to_groupdn(topo, _add_user, _aci_of_user): - """ - Test allow delete access to groupdn + """Test allow delete access to groupdn + :id: 7cf15992-68ad-11e8-85af-54e1ad30572c :setup: topo.standalone :steps: @@ -124,8 +124,8 @@ def test_allow_delete_access_to_groupdn(topo, _add_user, _aci_of_user): def test_allow_add_access_to_anyone(topo, _add_user, _aci_of_user): - """ - Test to allow add access to anyone + """Test to allow add access to anyone + :id: 5ca31cc4-68e0-11e8-8666-8c16451d917b :setup: topo.standalone :steps: @@ -160,8 +160,8 @@ def test_allow_add_access_to_anyone(topo, _add_user, _aci_of_user): def test_allow_delete_access_to_anyone(topo, _add_user, _aci_of_user): - """ - Test to allow delete access to anyone + """Test to allow delete access to anyone + :id: f5447c7e-68e1-11e8-84c4-8c16451d917b :setup: server :steps: @@ -191,8 +191,8 @@ def test_allow_delete_access_to_anyone(topo, _add_user, _aci_of_user): def test_allow_delete_access_not_to_userdn(topo, _add_user, _aci_of_user): - """ - Test to Allow delete access to != userdn + """Test to Allow delete access to != userdn + :id: 00637f6e-68e3-11e8-92a3-8c16451d917b :setup: server :steps: @@ -224,8 +224,8 @@ def test_allow_delete_access_not_to_userdn(topo, _add_user, _aci_of_user): def test_allow_delete_access_not_to_group(topo, _add_user, _aci_of_user): - """ - Test to Allow delete access to != groupdn + """Test to Allow delete access to != groupdn + :id: f58fc8b0-68e5-11e8-9313-8c16451d917b :setup: server :steps: @@ -263,8 +263,8 @@ def test_allow_delete_access_not_to_group(topo, _add_user, _aci_of_user): def test_allow_add_access_to_parent(topo, _add_user, _aci_of_user): - """ - Test to Allow add privilege to parent + """Test to Allow add privilege to parent + :id: 9f099845-9dbc-412f-bdb9-19a5ea729694 :setup: server :steps: @@ -299,8 +299,8 @@ def test_allow_add_access_to_parent(topo, _add_user, _aci_of_user): def test_allow_delete_access_to_parent(topo, _add_user, _aci_of_user): - """ - Test to Allow delete access to parent + """Test to Allow delete access to parent + :id: 2dd7f624-68e7-11e8-8591-8c16451d917b :setup: server :steps: @@ -333,10 +333,10 @@ def test_allow_delete_access_to_parent(topo, _add_user, _aci_of_user): new_user.delete() -def test_allow_delete_access_to_dynamic_group(topo, _add_user, _aci_of_user): +def test_allow_delete_access_to_dynamic_group(topo, _add_user, _aci_of_user, request): + + """Test to Allow delete access to dynamic group - """ - Test to Allow delete access to dynamic group :id: 14ffa452-68ed-11e8-a60d-8c16451d917b :setup: server :steps: @@ -361,8 +361,8 @@ def test_allow_delete_access_to_dynamic_group(topo, _add_user, _aci_of_user): # Set ACI Domain(topo.standalone, DEFAULT_SUFFIX).\ - add("aci", f'(target = ldap:///{DEFAULT_SUFFIX})(targetattr=*)' - f'(version 3.0; acl "$tet_thistest"; ' + add("aci", f'(target = ldap:///{DEFAULT_SUFFIX})(targetattr="*")' + f'(version 3.0; acl "{request.node.name}"; ' f'allow (delete) (groupdn = "ldap:///{group.dn}"); )') # create connection with USER_WITH_ACI_DELADD @@ -372,10 +372,10 @@ def test_allow_delete_access_to_dynamic_group(topo, _add_user, _aci_of_user): UserAccount(conn, USER_DELADD).delete() -def test_allow_delete_access_to_dynamic_group_uid(topo, _add_user, _aci_of_user): +def test_allow_delete_access_to_dynamic_group_uid(topo, _add_user, _aci_of_user, request): + + """Test to Allow delete access to dynamic group - """ - Test to Allow delete access to dynamic group :id: 010a4f20-752a-4173-b763-f520c7a85b82 :setup: server :steps: @@ -401,7 +401,7 @@ def test_allow_delete_access_to_dynamic_group_uid(topo, _add_user, _aci_of_user) # Set ACI Domain(topo.standalone, DEFAULT_SUFFIX).\ add("aci", f'(target = ldap:///{DEFAULT_SUFFIX})' - f'(targetattr=uid)(version 3.0; acl "$tet_thistest"; ' + f'(targetattr="uid")(version 3.0; acl "{request.node.name}"; ' f'allow (delete) (groupdn = "ldap:///{group.dn}"); )') # create connection with USER_WITH_ACI_DELADD @@ -411,10 +411,10 @@ def test_allow_delete_access_to_dynamic_group_uid(topo, _add_user, _aci_of_user) UserAccount(conn, USER_DELADD).delete() -def test_allow_delete_access_not_to_dynamic_group(topo, _add_user, _aci_of_user): +def test_allow_delete_access_not_to_dynamic_group(topo, _add_user, _aci_of_user, request): + + """Test to Allow delete access to != dynamic group - """ - Test to Allow delete access to != dynamic group :id: 9ecb139d-bca8-428e-9044-fd89db5a3d14 :setup: server :steps: @@ -439,7 +439,7 @@ def test_allow_delete_access_not_to_dynamic_group(topo, _add_user, _aci_of_user) # Set ACI Domain(topo.standalone, DEFAULT_SUFFIX).\ add("aci", f'(target = ldap:///{DEFAULT_SUFFIX})' - f'(targetattr=*)(version 3.0; acl "$tet_thistest"; ' + f'(targetattr="*")(version 3.0; acl "{request.node.name}"; ' f'allow (delete) (groupdn != "ldap:///{group.dn}"); )') # create connection with USER_WITH_ACI_DELADD diff --git a/dirsrvtests/tests/suites/acl/enhanced_aci_modrnd_test.py b/dirsrvtests/tests/suites/acl/enhanced_aci_modrnd_test.py index ca9456935..0cecde4b8 100644 --- a/dirsrvtests/tests/suites/acl/enhanced_aci_modrnd_test.py +++ b/dirsrvtests/tests/suites/acl/enhanced_aci_modrnd_test.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2016 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -31,15 +31,13 @@ def env_setup(topology_st): log.info("Add a container: %s" % CONTAINER_1) topology_st.standalone.add_s(Entry((CONTAINER_1, - {'objectclass': 'top', - 'objectclass': 'organizationalunit', + {'objectclass': ['top','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', + {'objectclass': ['top', 'organizationalunit'], 'ou': CONTAINER_2_OU, }))) @@ -75,13 +73,13 @@ def test_enhanced_aci_modrnd(topology_st, env_setup): :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) + 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 diff --git a/dirsrvtests/tests/suites/acl/globalgroup_part2_test.py b/dirsrvtests/tests/suites/acl/globalgroup_part2_test.py index b10fb1b65..7474f61f0 100644 --- a/dirsrvtests/tests/suites/acl/globalgroup_part2_test.py +++ b/dirsrvtests/tests/suites/acl/globalgroup_part2_test.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2019 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -70,6 +70,14 @@ def test_user(request, topo): 'userPassword': PW_DM }) + # Add anonymous access aci + ACI_TARGET = "(targetattr=\"*\")(target = \"ldap:///%s\")" % (DEFAULT_SUFFIX) + ACI_ALLOW = "(version 3.0; acl \"Anonymous Read access\"; allow (read,search,compare)" + ACI_SUBJECT = "(userdn=\"ldap:///anyone\");)" + ANON_ACI = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT + suffix = Domain(topo.standalone, DEFAULT_SUFFIX) + suffix.add('aci', ANON_ACI) + uas = UserAccounts(topo.standalone, DEFAULT_SUFFIX, 'uid=GROUPDNATTRSCRATCHENTRY_GLOBAL,ou=nestedgroup') for demo1 in ['c1', 'CHILD1_GLOBAL']: uas.create(properties={ @@ -112,7 +120,7 @@ def test_undefined_in_group_eval_five(topo, test_user, aci_of_user): 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) groupdn != "ldap:///{}\ || ldap:///{}";)'.format(ALLGROUPS_GLOBAL, GROUPF_GLOBAL)) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) groupdn != "ldap:///{}\ || ldap:///{}";)'.format(ALLGROUPS_GLOBAL, GROUPF_GLOBAL)) conn = UserAccount(topo.standalone, DEEPUSER2_GLOBAL).bind(PW_DM) # This aci should NOT allow access user = UserAccount(conn, DEEPGROUPSCRATCHENTRY_GLOBAL) @@ -140,7 +148,7 @@ def test_undefined_in_group_eval_six(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) groupdn = "ldap:///{} || ldap:///{}" ;)'.format(GROUPH_GLOBAL, ALLGROUPS_GLOBAL)) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) groupdn = "ldap:///{} || ldap:///{}" ;)'.format(GROUPH_GLOBAL, ALLGROUPS_GLOBAL)) conn = UserAccount(topo.standalone, DEEPUSER3_GLOBAL).bind(PW_DM) # test UNDEFINED in group user = UserAccount(conn, DEEPGROUPSCRATCHENTRY_GLOBAL) @@ -168,7 +176,7 @@ def test_undefined_in_group_eval_seven(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) groupdn = "ldap:///{}\ || ldap:///{}";)'.format(ALLGROUPS_GLOBAL, GROUPH_GLOBAL)) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) groupdn = "ldap:///{}\ || ldap:///{}";)'.format(ALLGROUPS_GLOBAL, GROUPH_GLOBAL)) conn = UserAccount(topo.standalone, DEEPUSER3_GLOBAL).bind(PW_DM) # test UNDEFINED in group user = UserAccount(conn, DEEPGROUPSCRATCHENTRY_GLOBAL) @@ -196,7 +204,7 @@ def test_undefined_in_group_eval_eight(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) groupdn != "ldap:///{} || ldap:///{} || ldap:///{}" ;)'.format(GROUPH_GLOBAL, GROUPA_GLOBAL, ALLGROUPS_GLOBAL)) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) groupdn != "ldap:///{} || ldap:///{} || ldap:///{}" ;)'.format(GROUPH_GLOBAL, GROUPA_GLOBAL, ALLGROUPS_GLOBAL)) conn = UserAccount(topo.standalone, DEEPUSER3_GLOBAL).bind(PW_DM) # test UNDEFINED in group user = UserAccount(conn, DEEPGROUPSCRATCHENTRY_GLOBAL) @@ -224,7 +232,7 @@ def test_undefined_in_group_eval_nine(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) groupdn != "ldap:///{}\ || ldap:///{} || ldap:///{}";)'.format(ALLGROUPS_GLOBAL, GROUPA_GLOBAL, GROUPH_GLOBAL)) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) groupdn != "ldap:///{}\ || ldap:///{} || ldap:///{}";)'.format(ALLGROUPS_GLOBAL, GROUPA_GLOBAL, GROUPH_GLOBAL)) conn = UserAccount(topo.standalone, DEEPUSER3_GLOBAL).bind(PW_DM) # test UNDEFINED in group user = UserAccount(conn, DEEPGROUPSCRATCHENTRY_GLOBAL) @@ -252,7 +260,7 @@ def test_undefined_in_group_eval_ten(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) userattr = "description#GROUPDN";)') + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) userattr = "description#GROUPDN";)') user = UserAccount(topo.standalone, DEEPGROUPSCRATCHENTRY_GLOBAL) user.add("description", [ALLGROUPS_GLOBAL, GROUPG_GLOBAL]) conn = UserAccount(topo.standalone, DEEPUSER_GLOBAL).bind(PW_DM) @@ -281,7 +289,7 @@ def test_undefined_in_group_eval_eleven(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) not( userattr = "description#GROUPDN");)') + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) not( userattr = "description#GROUPDN");)') user = UserAccount(topo.standalone, DEEPGROUPSCRATCHENTRY_GLOBAL) user.add("description", [ALLGROUPS_GLOBAL, GROUPH_GLOBAL]) conn = UserAccount(topo.standalone, DEEPUSER_GLOBAL).bind(PW_DM) @@ -312,7 +320,7 @@ def test_undefined_in_group_eval_twelve(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) userattr = "parent[0,1].description#GROUPDN";)') + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) userattr = "parent[0,1].description#GROUPDN";)') user = UserAccount(topo.standalone, GROUPDNATTRSCRATCHENTRY_GLOBAL) user.add("description", [ALLGROUPS_GLOBAL, GROUPD_GLOBAL]) conn = UserAccount(topo.standalone, DEEPUSER_GLOBAL).bind(PW_DM) @@ -341,7 +349,7 @@ def test_undefined_in_group_eval_fourteen(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) userattr = "parent[0,1].description#GROUPDN";)') + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) userattr = "parent[0,1].description#GROUPDN";)') user = UserAccount(topo.standalone, GROUPDNATTRSCRATCHENTRY_GLOBAL) user.add("description", [ALLGROUPS_GLOBAL, GROUPG_GLOBAL]) conn = UserAccount(topo.standalone, DEEPUSER2_GLOBAL).bind(PW_DM) @@ -372,7 +380,7 @@ def test_undefined_in_group_eval_fifteen(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) userattr = "parent[0,1].description#USERDN";)') + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) userattr = "parent[0,1].description#USERDN";)') UserAccount(topo.standalone, NESTEDGROUP_OU_GLOBAL).add("description", DEEPUSER_GLOBAL) # Here do the same tests for userattr with the parent keyword. conn = UserAccount(topo.standalone, DEEPUSER_GLOBAL).bind(PW_DM) @@ -399,7 +407,7 @@ def test_undefined_in_group_eval_sixteen(topo, test_user, aci_of_user): 5. Operation should succeed """ domain = Domain(topo.standalone, DEFAULT_SUFFIX) - domain.add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) not ( userattr = "parent[0,1].description#USERDN");)') + domain.add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) not ( userattr = "parent[0,1].description#USERDN");)') domain.add("description", DEEPUSER_GLOBAL) conn = UserAccount(topo.standalone, DEEPUSER_GLOBAL).bind(PW_DM) # Test with parent keyword with not key @@ -427,7 +435,7 @@ def test_undefined_in_group_eval_seventeen(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) userattr = "parent[0,1].description#GROUPDN";)') + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) userattr = "parent[0,1].description#GROUPDN";)') user = UserAccount(topo.standalone, GROUPDNATTRSCRATCHENTRY_GLOBAL) # Test with the parent keyord user.add("description", [ALLGROUPS_GLOBAL, GROUPD_GLOBAL]) @@ -455,7 +463,7 @@ def test_undefined_in_group_eval_eighteen(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) not (userattr = "parent[0,1].description#GROUPDN" );)') + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) not (userattr = "parent[0,1].description#GROUPDN" );)') user = UserAccount(topo.standalone, GROUPDNATTRSCRATCHENTRY_GLOBAL) # Test with parent keyword with not key user.add("description", [ALLGROUPS_GLOBAL, GROUPH_GLOBAL]) diff --git a/dirsrvtests/tests/suites/acl/globalgroup_test.py b/dirsrvtests/tests/suites/acl/globalgroup_test.py index 58c4392e5..dc51a8170 100644 --- a/dirsrvtests/tests/suites/acl/globalgroup_test.py +++ b/dirsrvtests/tests/suites/acl/globalgroup_test.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2019 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -72,6 +72,14 @@ def test_user(request, topo): 'userPassword': PW_DM }) + # Add anonymous access aci + ACI_TARGET = "(targetattr=\"*\")(target = \"ldap:///%s\")" % (DEFAULT_SUFFIX) + ACI_ALLOW = "(version 3.0; acl \"Anonymous Read access\"; allow (read,search,compare)" + ACI_SUBJECT = "(userdn=\"ldap:///anyone\");)" + ANON_ACI = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT + suffix = Domain(topo.standalone, DEFAULT_SUFFIX) + suffix.add('aci', ANON_ACI) + uas = UserAccounts(topo.standalone, DEFAULT_SUFFIX, 'ou=nestedgroup') for demo1 in ['DEEPUSER_GLOBAL', 'scratchEntry', 'DEEPUSER2_GLOBAL', 'DEEPUSER1_GLOBAL', 'DEEPUSER3_GLOBAL', 'GROUPDNATTRSCRATCHENTRY_GLOBAL', 'newChild']: @@ -361,7 +369,7 @@ def test_undefined_in_group_eval_two(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) groupdn = "ldap:///{}\ || ldap:///{}";)'.format(ALLGROUPS_GLOBAL, GROUPG_GLOBAL)) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) groupdn = "ldap:///{}\ || ldap:///{}";)'.format(ALLGROUPS_GLOBAL, GROUPG_GLOBAL)) conn = UserAccount(topo.standalone, DEEPUSER_GLOBAL).bind(PW_DM) user = UserAccount(conn, DEEPGROUPSCRATCHENTRY_GLOBAL) # This aci should allow access @@ -389,7 +397,7 @@ def test_undefined_in_group_eval_three(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) groupdn = "ldap:///{}\ || ldap:///{}";)'.format(GROUPG_GLOBAL, ALLGROUPS_GLOBAL)) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) groupdn = "ldap:///{}\ || ldap:///{}";)'.format(GROUPG_GLOBAL, ALLGROUPS_GLOBAL)) conn = UserAccount(topo.standalone, DEEPUSER_GLOBAL).bind(PW_DM) user = Domain(conn, DEEPGROUPSCRATCHENTRY_GLOBAL) # test UNDEFINED in group @@ -417,7 +425,7 @@ def test_undefined_in_group_eval_four(topo, test_user, aci_of_user): 4. Operation should succeed 5. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr=*)(version 3.0; aci "tester"; allow(all) groupdn != "ldap:///{}\ || ldap:///{}";)'.format(ALLGROUPS_GLOBAL, GROUPG_GLOBAL)) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(targetattr="*")(version 3.0; aci "tester"; allow(all) groupdn != "ldap:///{}\ || ldap:///{}";)'.format(ALLGROUPS_GLOBAL, GROUPG_GLOBAL)) conn = UserAccount(topo.standalone, DEEPUSER1_GLOBAL).bind(PW_DM) # test UNDEFINED in group user = UserAccount(conn, DEEPGROUPSCRATCHENTRY_GLOBAL) diff --git a/dirsrvtests/tests/suites/acl/keywords_part2_test.py b/dirsrvtests/tests/suites/acl/keywords_part2_test.py index c2aa9ac53..642e65bad 100644 --- a/dirsrvtests/tests/suites/acl/keywords_part2_test.py +++ b/dirsrvtests/tests/suites/acl/keywords_part2_test.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2019 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -68,7 +68,7 @@ def test_access_from_certain_network_only_ip(topo, add_user, aci_of_user): # Add ACI domain = Domain(topo.standalone, DEFAULT_SUFFIX) - domain.add("aci", f'(target = "ldap:///{IP_OU_KEY}")(targetattr=*)(version 3.0; aci "IP aci"; ' + domain.add("aci", f'(target = "ldap:///{IP_OU_KEY}")(targetattr=\"*\")(version 3.0; aci "IP aci"; ' f'allow(all)userdn = "ldap:///{NETSCAPEIP_KEY}" and ip = "{ip_ip}" ;)') # create a new connection for the test @@ -76,12 +76,13 @@ def test_access_from_certain_network_only_ip(topo, add_user, aci_of_user): # Perform Operation org = OrganizationalUnit(conn, IP_OU_KEY) org.replace("seeAlso", "cn=1") + # remove the aci - domain.ensure_removed("aci", f'(target = "ldap:///{IP_OU_KEY}")(targetattr=*)(version 3.0; aci ' + domain.ensure_removed("aci", f'(target = "ldap:///{IP_OU_KEY}")(targetattr=\"*\")(version 3.0; aci ' f'"IP aci"; allow(all)userdn = "ldap:///{NETSCAPEIP_KEY}" and ' f'ip = "{ip_ip}" ;)') # Now add aci with new ip - domain.add("aci", f'(target = "ldap:///{IP_OU_KEY}")(targetattr=*)(version 3.0; aci "IP aci"; ' + domain.add("aci", f'(target = "ldap:///{IP_OU_KEY}")(targetattr="*")(version 3.0; aci "IP aci"; ' f'allow(all)userdn = "ldap:///{NETSCAPEIP_KEY}" and ip = "100.1.1.1" ;)') # After changing the ip user cant access data @@ -106,10 +107,11 @@ def test_connectin_from_an_unauthorized_network(topo, add_user, aci_of_user): """ # Find the ip from ds logs , as we need to know the exact ip used by ds to run the instances. ip_ip = topo.standalone.ds_access_log.match('.* connection from ')[0].split()[-1] + # Add ACI domain = Domain(topo.standalone, DEFAULT_SUFFIX) domain.add("aci", f'(target = "ldap:///{IP_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "IP aci"; ' + f'(targetattr="*")(version 3.0; aci "IP aci"; ' f'allow(all) userdn = "ldap:///{NETSCAPEIP_KEY}" ' f'and ip != "{ip_ip}" ;)') @@ -122,7 +124,7 @@ def test_connectin_from_an_unauthorized_network(topo, add_user, aci_of_user): # Remove the ACI domain.ensure_removed('aci', domain.get_attr_vals('aci')[-1]) # Add new ACI - domain.add('aci', f'(target = "ldap:///{IP_OU_KEY}")(targetattr=*)' + domain.add('aci', f'(target = "ldap:///{IP_OU_KEY}")(targetattr="*")' f'(version 3.0; aci "IP aci"; allow(all) ' f'userdn = "ldap:///{NETSCAPEIP_KEY}" and ip = "{ip_ip}" ;)') @@ -148,7 +150,7 @@ def test_ip_keyword_test_noip_cannot(topo, add_user, aci_of_user): # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", f'(target ="ldap:///{IP_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "IP aci"; allow(all) ' + f'(targetattr="*")(version 3.0; aci "IP aci"; allow(all) ' f'userdn = "ldap:///{FULLIP_KEY}" and ip = "*" ;)') # Create a new connection for this test. @@ -177,7 +179,7 @@ def test_user_can_access_the_data_at_any_time(topo, add_user, aci_of_user): # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", f'(target = "ldap:///{TIMEOFDAY_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "Timeofday aci"; ' + f'(targetattr="*")(version 3.0; aci "Timeofday aci"; ' f'allow(all) userdn ="ldap:///{FULLWORKER_KEY}" and ' f'(timeofday >= "0000" and timeofday <= "2359") ;)') @@ -206,7 +208,7 @@ def test_user_can_access_the_data_only_in_the_morning(topo, add_user, aci_of_use # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", f'(target = "ldap:///{TIMEOFDAY_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "Timeofday aci"; ' + f'(targetattr="*")(version 3.0; aci "Timeofday aci"; ' f'allow(all) userdn = "ldap:///{DAYWORKER_KEY}" ' f'and timeofday < "1200" ;)') @@ -239,7 +241,7 @@ def test_user_can_access_the_data_only_in_the_afternoon(topo, add_user, aci_of_u # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", f'(target = "ldap:///{TIMEOFDAY_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "Timeofday aci"; ' + f'(targetattr="*")(version 3.0; aci "Timeofday aci"; ' f'allow(all) userdn = "ldap:///{NIGHTWORKER_KEY}" ' f'and timeofday > \'1200\' ;)') @@ -275,7 +277,7 @@ def test_timeofday_keyword(topo, add_user, aci_of_user): # Add ACI domain = Domain(topo.standalone, DEFAULT_SUFFIX) domain.add("aci", f'(target = "ldap:///{TIMEOFDAY_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "Timeofday aci"; ' + f'(targetattr="*")(version 3.0; aci "Timeofday aci"; ' f'allow(all) userdn = "ldap:///{NOWORKER_KEY}" ' f'and timeofday = \'{now_1}\' ;)') @@ -312,7 +314,7 @@ def test_dayofweek_keyword_test_everyday_can_access(topo, add_user, aci_of_user) # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", f'(target = "ldap:///{DAYOFWEEK_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "Dayofweek aci"; ' + f'(targetattr="*")(version 3.0; aci "Dayofweek aci"; ' f'allow(all) userdn = "ldap:///{EVERYDAY_KEY}" and ' f'dayofweek = "Sun, Mon, Tue, Wed, Thu, Fri, Sat" ;)') @@ -342,7 +344,7 @@ def test_dayofweek_keyword_today_can_access(topo, add_user, aci_of_user): # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", f'(target = "ldap:///{DAYOFWEEK_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "Dayofweek aci"; ' + f'(targetattr="*")(version 3.0; aci "Dayofweek aci"; ' f'allow(all) userdn = "ldap:///{TODAY_KEY}" ' f'and dayofweek = \'{today_1}\' ;)') @@ -371,7 +373,7 @@ def test_user_cannot_access_the_data_at_all(topo, add_user, aci_of_user): # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", f'(target = "ldap:///{DAYOFWEEK_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "Dayofweek aci"; ' + f'(targetattr="*")(version 3.0; aci "Dayofweek aci"; ' f'allow(all) userdn = "ldap:///{TODAY_KEY}" ' f'and dayofweek = "$NEW_DATE" ;)') diff --git a/dirsrvtests/tests/suites/acl/keywords_test.py b/dirsrvtests/tests/suites/acl/keywords_test.py index 138e3ede1..0174152e3 100644 --- a/dirsrvtests/tests/suites/acl/keywords_test.py +++ b/dirsrvtests/tests/suites/acl/keywords_test.py @@ -39,11 +39,11 @@ NONE_2_KEY = "uid=NONE_2_KEY,{}".format(AUTHMETHOD_OU_KEY) NONE_ACI_KEY = f'(target = "ldap:///{AUTHMETHOD_OU_KEY}")' \ - f'(targetattr=*)(version 3.0; aci "Authmethod aci"; ' \ + f'(targetattr="*")(version 3.0; aci "Authmethod aci"; ' \ f'allow(all) userdn = "ldap:///{NONE_1_KEY}" and authmethod = "none" ;)' SIMPLE_ACI_KEY = f'(target = "ldap:///{AUTHMETHOD_OU_KEY}")' \ - f'(targetattr=*)(version 3.0; aci "Authmethod aci"; ' \ + f'(targetattr="*")(version 3.0; aci "Authmethod aci"; ' \ f'allow(all) userdn = "ldap:///{SIMPLE_1_KEY}" and authmethod = "simple" ;)' @@ -55,8 +55,7 @@ def _add_aci(topo, name): def test_user_binds_with_a_password_and_can_access_the_data(topo, add_user, aci_of_user): - """ - User binds with a password and can access the data as per the ACI. + """User binds with a password and can access the data as per the ACI. :id: f6c4b6f0-7ac4-11e8-a517-8c16451d917b :setup: Standalone Server @@ -78,8 +77,7 @@ def test_user_binds_with_a_password_and_can_access_the_data(topo, add_user, aci_ def test_user_binds_with_a_bad_password_and_cannot_access_the_data(topo, add_user, aci_of_user): - """ - User binds with a BAD password and cannot access the data . + """User binds with a BAD password and cannot access the data . :id: 0397744e-7ac5-11e8-bfb1-8c16451d917b :setup: Standalone Server @@ -98,8 +96,7 @@ def test_user_binds_with_a_bad_password_and_cannot_access_the_data(topo, add_use def test_anonymous_user_cannot_access_the_data(topo, add_user, aci_of_user): - """ - Anonymous user cannot access the data + """Anonymous user cannot access the data :id: 0821a55c-7ac5-11e8-b214-8c16451d917b :setup: Standalone Server @@ -124,8 +121,7 @@ def test_anonymous_user_cannot_access_the_data(topo, add_user, aci_of_user): def test_authenticated_but_has_no_rigth_on_the_data(topo, add_user, aci_of_user): - """ - User has a password. He is authenticated but has no rigth on the data. + """User has a password. He is authenticated but has no rigth on the data. :id: 11be7ebe-7ac5-11e8-b754-8c16451d917b :setup: Standalone Server @@ -150,10 +146,9 @@ def test_authenticated_but_has_no_rigth_on_the_data(topo, add_user, aci_of_user) def test_the_bind_client_is_accessing_the_directory(topo, add_user, aci_of_user): - """ - The bind rule is evaluated to be true if the client is accessing the directory as per the ACI. + """The bind rule is evaluated to be true if the client is accessing the directory as per the ACI. - :id: 1715bfb2-7ac5-11e8-8f2c-8c16451d917b + :id: 1715bfb2-7ac5-11e8-8f2c-8c16451d917b :setup: Standalone Server :steps: 1. Add test entry @@ -175,8 +170,7 @@ def test_the_bind_client_is_accessing_the_directory(topo, add_user, aci_of_user) def test_users_binds_with_a_password_and_can_access_the_data( topo, add_user, aci_of_user): - """ - User binds with a password and can access the data as per the ACI. + """User binds with a password and can access the data as per the ACI. :id: 1bd01cb4-7ac5-11e8-a2f1-8c16451d917b :setup: Standalone Server @@ -199,8 +193,7 @@ def test_users_binds_with_a_password_and_can_access_the_data( def test_user_binds_without_any_password_and_cannot_access_the_data(topo, add_user, aci_of_user): - """ - User binds without any password and cannot access the data + """User binds without any password and cannot access the data :id: 205777fa-7ac5-11e8-ba2f-8c16451d917b :setup: Standalone Server @@ -227,8 +220,7 @@ def test_user_binds_without_any_password_and_cannot_access_the_data(topo, add_us def test_user_can_access_the_data_when_connecting_from_any_machine( topo, add_user, aci_of_user ): - """ - User can access the data when connecting from any machine as per the ACI. + """User can access the data when connecting from any machine as per the ACI. :id: 28cbc008-7ac5-11e8-934e-8c16451d917b :setup: Standalone Server @@ -244,7 +236,7 @@ def test_user_can_access_the_data_when_connecting_from_any_machine( # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX)\ .add("aci", f'(target ="ldap:///{DNS_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "DNS aci"; allow(all) ' + f'(targetattr="*")(version 3.0; aci "DNS aci"; allow(all) ' f'userdn = "ldap:///{FULLDNS_KEY}" and dns = "*" ;)') # Create a new connection for this test. @@ -256,8 +248,8 @@ def test_user_can_access_the_data_when_connecting_from_any_machine( def test_user_can_access_the_data_when_connecting_from_internal_ds_network_only( topo, add_user, aci_of_user ): - """ - User can access the data when connecting from internal ICNC network only as per the ACI. + """User can access the data when connecting from internal ICNC network only as per the ACI. + :id: 2cac2136-7ac5-11e8-8328-8c16451d917b :setup: Standalone Server :steps: @@ -273,9 +265,9 @@ def test_user_can_access_the_data_when_connecting_from_internal_ds_network_only( # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX).\ add("aci", [f'(target = "ldap:///{DNS_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "DNS aci"; ' + f'(targetattr="*")(version 3.0; aci "DNS aci"; ' f'allow(all) userdn = "ldap:///{SUNDNS_KEY}" and dns = "*redhat.com" ;)', - f'(target = "ldap:///{DNS_OU_KEY}")(targetattr=*)' + f'(target = "ldap:///{DNS_OU_KEY}")(targetattr="*")' f'(version 3.0; aci "DNS aci"; allow(all) ' f'userdn = "ldap:///{SUNDNS_KEY}" and dns = "{dns_name}" ;)']) @@ -288,8 +280,7 @@ def test_user_can_access_the_data_when_connecting_from_internal_ds_network_only( def test_user_can_access_the_data_when_connecting_from_some_network_only( topo, add_user, aci_of_user ): - """ - User can access the data when connecting from some network only as per the ACI. + """User can access the data when connecting from some network only as per the ACI. :id: 3098512a-7ac5-11e8-af85-8c16451d917b :setup: Standalone Server @@ -306,7 +297,7 @@ def test_user_can_access_the_data_when_connecting_from_some_network_only( # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX)\ .add("aci", f'(target = "ldap:///{DNS_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "DNS aci"; allow(all) ' + f'(targetattr="*")(version 3.0; aci "DNS aci"; allow(all) ' f'userdn = "ldap:///{NETSCAPEDNS_KEY}" ' f'and dns = "{dns_name}" ;)') @@ -317,8 +308,7 @@ def test_user_can_access_the_data_when_connecting_from_some_network_only( def test_from_an_unauthorized_network(topo, add_user, aci_of_user): - """ - User cannot access the data when connecting from an unauthorized network as per the ACI. + """User cannot access the data when connecting from an unauthorized network as per the ACI. :id: 34cf9726-7ac5-11e8-bc12-8c16451d917b :setup: Standalone Server @@ -334,7 +324,7 @@ def test_from_an_unauthorized_network(topo, add_user, aci_of_user): # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX).\ add("aci", f'(target = "ldap:///{DNS_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "DNS aci"; allow(all) ' + f'(targetattr="*")(version 3.0; aci "DNS aci"; allow(all) ' f'userdn = "ldap:///{NETSCAPEDNS_KEY}" and dns != "red.iplanet.com" ;)') # Create a new connection for this test. @@ -345,8 +335,7 @@ def test_from_an_unauthorized_network(topo, add_user, aci_of_user): def test_user_cannot_access_the_data_when_connecting_from_an_unauthorized_network_2( topo, add_user, aci_of_user): - """ - User cannot access the data when connecting from an unauthorized network as per the ACI. + """User cannot access the data when connecting from an unauthorized network as per the ACI. :id: 396bdd44-7ac5-11e8-8014-8c16451d917b :setup: Standalone Server @@ -362,7 +351,7 @@ def test_user_cannot_access_the_data_when_connecting_from_an_unauthorized_networ # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX).\ add("aci", f'(target = "ldap:///{DNS_OU_KEY}")' - f'(targetattr=*)(version 3.0; aci "DNS aci"; allow(all) ' + f'(targetattr="*")(version 3.0; aci "DNS aci"; allow(all) ' f'userdn = "ldap:///{NETSCAPEDNS_KEY}" ' f'and dnsalias != "www.redhat.com" ;)') @@ -373,8 +362,8 @@ def test_user_cannot_access_the_data_when_connecting_from_an_unauthorized_networ def test_user_cannot_access_the_data_if_not_from_a_certain_domain(topo, add_user, aci_of_user): - """ - User cannot access the data if not from a certain domain as per the ACI. + """User cannot access the data if not from a certain domain as per the ACI. + :id: 3d658972-7ac5-11e8-930f-8c16451d917b :setup: Standalone Server :steps: @@ -388,7 +377,7 @@ def test_user_cannot_access_the_data_if_not_from_a_certain_domain(topo, add_user """ # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX).\ - add("aci", f'(target = "ldap:///{DNS_OU_KEY}")(targetattr=*)' + add("aci", f'(target = "ldap:///{DNS_OU_KEY}")(targetattr="*")' f'(version 3.0; aci "DNS aci"; allow(all) ' f'userdn = "ldap:///{NODNS_KEY}" ' f'and dns = "RAP.rock.SALSA.house.COM" ;)') @@ -402,8 +391,7 @@ def test_user_cannot_access_the_data_if_not_from_a_certain_domain(topo, add_user def test_dnsalias_keyword_test_nodns_cannot(topo, add_user, aci_of_user): - """ - Dnsalias Keyword NODNS_KEY cannot assess data as per the ACI. + """Dnsalias Keyword NODNS_KEY cannot assess data as per the ACI. :id: 41b467be-7ac5-11e8-89a3-8c16451d917b :setup: Standalone Server @@ -418,7 +406,7 @@ def test_dnsalias_keyword_test_nodns_cannot(topo, add_user, aci_of_user): """ # Add ACI Domain(topo.standalone, DEFAULT_SUFFIX).\ - add("aci", f'(target = "ldap:///{DNS_OU_KEY}")(targetattr=*)' + add("aci", f'(target = "ldap:///{DNS_OU_KEY}")(targetattr="*")' f'(version 3.0; aci "DNS aci"; allow(all) ' f'userdn = "ldap:///{NODNS_KEY}" and ' f'dnsalias = "RAP.rock.SALSA.house.COM" ;)') @@ -434,8 +422,7 @@ def test_dnsalias_keyword_test_nodns_cannot(topo, add_user, aci_of_user): @pytest.mark.bz1710848 @pytest.mark.parametrize("ip_addr", ['127.0.0.1', "[::1]"]) def test_user_can_access_from_ipv4_or_ipv6_address(topo, add_user, aci_of_user, ip_addr): - """ - User can modify the data when accessing the server from the allowed IPv4 and IPv6 addresses + """User can modify the data when accessing the server from the allowed IPv4 and IPv6 addresses :id: 461e761e-7ac5-11e8-9ae4-8c16451d917b :parametrized: yes @@ -451,7 +438,7 @@ def test_user_can_access_from_ipv4_or_ipv6_address(topo, add_user, aci_of_user, """ # Add ACI that contains both IPv4 and IPv6 Domain(topo.standalone, DEFAULT_SUFFIX).\ - add("aci", f'(target ="ldap:///{IP_OU_KEY}")(targetattr=*) ' + add("aci", f'(target ="ldap:///{IP_OU_KEY}")(targetattr="*") ' f'(version 3.0; aci "IP aci"; allow(all) ' f'userdn = "ldap:///{FULLIP_KEY}" and (ip = "127.0.0.1" or ip = "::1");)') diff --git a/dirsrvtests/tests/suites/acl/misc_test.py b/dirsrvtests/tests/suites/acl/misc_test.py index 8f122b7a7..5f0e3eb72 100644 --- a/dirsrvtests/tests/suites/acl/misc_test.py +++ b/dirsrvtests/tests/suites/acl/misc_test.py @@ -1,6 +1,6 @@ """ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2019 RED Hat, Inc. +# Copyright (C) 2020 RED Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -8,6 +8,7 @@ # --- END COPYRIGHT BLOCK ---- """ +import ldap import os import pytest @@ -21,8 +22,6 @@ from lib389.topologies import topology_st as topo from lib389.idm.domain import Domain from lib389.plugins import ACLPlugin -import ldap - pytestmark = pytest.mark.tier1 PEOPLE = "ou=PEOPLE,{}".format(DEFAULT_SUFFIX) @@ -37,7 +36,19 @@ def aci_of_user(request, topo): :param request: :param topo: """ - aci_list = Domain(topo.standalone, DEFAULT_SUFFIX).get_attr_vals('aci') + + # Add anonymous access aci + ACI_TARGET = "(targetattr != \"userpassword\")(target = \"ldap:///%s\")" % (DEFAULT_SUFFIX) + ACI_ALLOW = "(version 3.0; acl \"Anonymous Read access\"; allow (read,search,compare)" + ACI_SUBJECT = "(userdn=\"ldap:///anyone\");)" + ANON_ACI = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT + suffix = Domain(topo.standalone, DEFAULT_SUFFIX) + try: + suffix.add('aci', ANON_ACI) + except ldap.TYPE_OR_VALUE_EXISTS: + pass + + aci_list = suffix.get_attr_vals('aci') def finofaci(): """ @@ -78,8 +89,8 @@ def clean(request, topo): def test_accept_aci_in_addition_to_acl(topo, clean, aci_of_user): - """ - Misc Test 2 accept aci in addition to acl + """Misc Test 2 accept aci in addition to acl + :id: 8e9408fa-7db8-11e8-adaa-8c16451d917b :setup: Standalone Instance :steps: @@ -96,7 +107,7 @@ def test_accept_aci_in_addition_to_acl(topo, clean, aci_of_user): for i in [('mail', 'anujborah@okok.com'), ('givenname', 'Anuj'), ('userPassword', PW_DM)]: user.set(i[0], i[1]) - aci_target = "(targetattr=givenname)" + aci_target = '(targetattr="givenname")' aci_allow = ('(version 3.0; acl "Name of the ACI"; deny (read, search, compare, write)') aci_subject = 'userdn="ldap:///anyone";)' Domain(topo.standalone, CONTAINER_1_DELADD).add("aci", aci_target + aci_allow + aci_subject) @@ -115,9 +126,9 @@ def test_accept_aci_in_addition_to_acl(topo, clean, aci_of_user): @pytest.mark.bz334451 def test_more_then_40_acl_will_crash_slapd(topo, clean, aci_of_user): - """ - bug 334451 : more then 40 acl will crash slapd + """bug 334451 : more then 40 acl will crash slapd superseded by Bug 772778 - acl cache overflown problem with > 200 acis + :id: 93a44c60-7db8-11e8-9439-8c16451d917b :setup: Standalone Instance :steps: @@ -132,7 +143,7 @@ def test_more_then_40_acl_will_crash_slapd(topo, clean, aci_of_user): uas = UserAccounts(topo.standalone, DEFAULT_SUFFIX, rdn='ou=Accounting') user = uas.create_test_user() - aci_target = '(target ="ldap:///{}")(targetattr !="userPassword")'.format(CONTAINER_1_DELADD) + aci_target = '(target ="ldap:///{}")(targetattr!="userPassword")'.format(CONTAINER_1_DELADD) # more_then_40_acl_will not crash_slapd for i in range(40): aci_allow = '(version 3.0;acl "ACI_{}";allow (read, search, compare)'.format(i) @@ -147,9 +158,9 @@ def test_more_then_40_acl_will_crash_slapd(topo, clean, aci_of_user): @pytest.mark.bz345643 def test_search_access_should_not_include_read_access(topo, clean, aci_of_user): - """ - bug 345643 + """bug 345643 Misc Test 4 search access should not include read access + :id: 98ab173e-7db8-11e8-a309-8c16451d917b :setup: Standalone Instance :steps: @@ -163,7 +174,7 @@ def test_search_access_should_not_include_read_access(topo, clean, aci_of_user): """ assert Domain(topo.standalone, DEFAULT_SUFFIX).present('aci') Domain(topo.standalone, DEFAULT_SUFFIX)\ - .add("aci", [f'(target ="ldap:///{DEFAULT_SUFFIX}")(targetattr !="userPassword")' + .replace("aci", [f'(target ="ldap:///{DEFAULT_SUFFIX}")(targetattr != "userPassword")' '(version 3.0;acl "anonymous access";allow (search)' '(userdn = "ldap:///anyone");)', f'(target="ldap:///{DEFAULT_SUFFIX}") (targetattr = "*")(version 3.0; ' @@ -176,13 +187,13 @@ def test_search_access_should_not_include_read_access(topo, clean, aci_of_user): conn = Anonymous(topo.standalone).bind() # search_access_should_not_include_read_access suffix = Domain(conn, DEFAULT_SUFFIX) - with pytest.raises(AssertionError): + with pytest.raises(Exception): assert suffix.present('aci') def test_only_allow_some_targetattr(topo, clean, aci_of_user): - """ - Misc Test 5 only allow some targetattr (1/2) + """Misc Test 5 only allow some targetattr (1/2) + :id: 9d27f048-7db8-11e8-a71c-8c16451d917b :setup: Standalone Instance :steps: @@ -211,17 +222,17 @@ def test_only_allow_some_targetattr(topo, clean, aci_of_user): # aci will allow only mail targetattr assert len(accounts.filter('(mail=*)')) == 2 # aci will allow only mail targetattr - assert not accounts.filter('(cn=*)') + assert not accounts.filter('(cn=*)', scope=1) # with root no , blockage - assert len(Accounts(topo.standalone, DEFAULT_SUFFIX).filter('(uid=*)')) == 2 + assert len(Accounts(topo.standalone, DEFAULT_SUFFIX).filter('(uid=*)', scope=1)) == 2 for i in uas.list(): i.delete() -def test_only_allow_some_targetattr_two(topo, clean, aci_of_user): - """ - Misc Test 6 only allow some targetattr (2/2)" +def test_only_allow_some_targetattr_two(topo, clean, aci_of_user, request): + """Misc Test 6 only allow some targetattr (2/2)" + :id: a188239c-7db8-11e8-903e-8c16451d917b :setup: Standalone Instance :steps: @@ -244,15 +255,15 @@ def test_only_allow_some_targetattr_two(topo, clean, aci_of_user): Domain(topo.standalone, DEFAULT_SUFFIX).\ replace("aci", '(target="ldap:///{}") (targetattr="mail||objectClass")' - '(targetfilter="cn=Anuj") (version 3.0; acl "$tet_thistest"; ' + '(targetfilter="cn=Anuj") (version 3.0; acl "{}"; ' 'allow (compare,read,search) ' - '(userdn = "ldap:///anyone"); )'.format(DEFAULT_SUFFIX)) + '(userdn = "ldap:///anyone"); )'.format(DEFAULT_SUFFIX, request.node.name)) conn = UserAccount(topo.standalone, user.dn).bind(PW_DM) # aci will allow only mail targetattr but only for cn=Anuj account = Accounts(conn, DEFAULT_SUFFIX) - assert len(account.filter('(mail=*)')) == 5 - assert not account.filter('(cn=*)') + assert len(account.filter('(mail=*)', scope=1)) == 5 + assert not account.filter('(cn=*)', scope=1) for i in account.filter('(mail=*)'): assert i.get_attr_val_utf8('mail') == 'anujborah@anujborah.com' @@ -261,8 +272,8 @@ def test_only_allow_some_targetattr_two(topo, clean, aci_of_user): conn = Anonymous(topo.standalone).bind() # aci will allow only mail targetattr but only for cn=Anuj account = Accounts(conn, DEFAULT_SUFFIX) - assert len(account.filter('(mail=*)')) == 5 - assert not account.filter('(cn=*)') + assert len(account.filter('(mail=*)', scope=1)) == 5 + assert not account.filter('(cn=*)', scope=1) for i in account.filter('(mail=*)'): assert i.get_attr_val_utf8('mail') == 'anujborah@anujborah.com' @@ -274,11 +285,10 @@ def test_only_allow_some_targetattr_two(topo, clean, aci_of_user): i.delete() - @pytest.mark.bz326000 def test_memberurl_needs_to_be_normalized(topo, clean, aci_of_user): - """ - Non-regression test for BUG 326000: MemberURL needs to be normalized + """Non-regression test for BUG 326000: MemberURL needs to be normalized + :id: a5d172e6-7db8-11e8-aca7-8c16451d917b :setup: Standalone Instance :steps: @@ -291,7 +301,7 @@ def test_memberurl_needs_to_be_normalized(topo, clean, aci_of_user): 3. Operation should succeed """ ou_ou = OrganizationalUnit(topo.standalone, "ou=PEOPLE,{}".format(DEFAULT_SUFFIX)) - ou_ou.set('aci', '(targetattr= *)' + ou_ou.set('aci', '(targetattr="*")' '(version 3.0; acl "tester"; allow(all) ' 'groupdn = "ldap:///cn =DYNGROUP,ou=PEOPLE, {}";)'.format(DEFAULT_SUFFIX)) @@ -323,8 +333,8 @@ def test_memberurl_needs_to_be_normalized(topo, clean, aci_of_user): @pytest.mark.bz624370 def test_greater_than_200_acls_can_be_created(topo, clean, aci_of_user): - """ - Misc 10, check that greater than 200 ACLs can be created. Bug 624370 + """Misc 10, check that greater than 200 ACLs can be created. Bug 624370 + :id: ac020252-7db8-11e8-8652-8c16451d917b :setup: Standalone Instance :steps: @@ -355,8 +365,8 @@ def test_greater_than_200_acls_can_be_created(topo, clean, aci_of_user): @pytest.mark.bz624453 def test_server_bahaves_properly_with_very_long_attribute_names(topo, clean, aci_of_user): - """ - Make sure the server bahaves properly with very long attribute names. Bug 624453. + """Make sure the server bahaves properly with very long attribute names. Bug 624453. + :id: b0d31942-7db8-11e8-a833-8c16451d917b :setup: Standalone Instance :steps: @@ -378,24 +388,23 @@ def test_server_bahaves_properly_with_very_long_attribute_names(topo, clean, aci def test_do_bind_as_201_distinct_users(topo, clean, aci_of_user): - """ - Do bind as 201 distinct users - Increase the nsslapd-aclpb-max-selected-acls in cn=ACL Plugin,cn=plugins,cn=config - Restart the server - Do bind as 201 distinct users + """Test bind as 201 distinct users + :id: c0060532-7db8-11e8-a124-8c16451d917b :setup: Standalone Instance :steps: - 1. Add test entry - 2. Add ACI - 3. User should follow ACI role + 1. Add test entries + 2. Increase the nsslapd-aclpb-max-selected-acls in cn=ACL Plugin,cn=plugins,cn=config + 3. Restart the server + 4. Do bind as 201 distinct users :expectedresults: - 1. Entry should be added - 2. Operation should succeed - 3. Operation should succeed + 1. Entries should be added + 2. Operation should succeed + 3. Operation should succeed + 4. Operation should succeed """ uas = UserAccounts(topo.standalone, DEFAULT_SUFFIX) - for i in range(50): + for i in range(201): user = uas.create_test_user(uid=i, gid=i) user.set('userPassword', PW_DM) @@ -408,7 +417,6 @@ def test_do_bind_as_201_distinct_users(topo, clean, aci_of_user): for i in range(len(uas.list())): uas.list()[i].bind(PW_DM) - if __name__ == "__main__": CURRENT_FILE = os.path.realpath(__file__) pytest.main("-s -v %s" % CURRENT_FILE) diff --git a/dirsrvtests/tests/suites/acl/modrdn_test.py b/dirsrvtests/tests/suites/acl/modrdn_test.py index f67f3e508..c4ae8eea5 100644 --- a/dirsrvtests/tests/suites/acl/modrdn_test.py +++ b/dirsrvtests/tests/suites/acl/modrdn_test.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2019 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -87,9 +87,9 @@ def _add_user(request, topo): request.addfinalizer(fin) -def test_allow_write_privilege_to_anyone(topo, _add_user, aci_of_user): - """ - Modrdn Test 1 Allow write privilege to anyone +def test_allow_write_privilege_to_anyone(topo, _add_user, aci_of_user, request): + """Modrdn Test 1 Allow write privilege to anyone + :id: 4406f12e-7932-11e8-9dea-8c16451d917b :setup: server :steps: @@ -102,8 +102,8 @@ def test_allow_write_privilege_to_anyone(topo, _add_user, aci_of_user): 3. Operation should succeed """ Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", - '(target ="ldap:///{}")(targetattr=*)(version 3.0;acl "$tet_thistest";allow ' - '(write) (userdn = "ldap:///anyone");)'.format(DEFAULT_SUFFIX)) + '(target ="ldap:///{}")(targetattr="*")(version 3.0;acl "{}";allow ' + '(write) (userdn = "ldap:///anyone");)'.format(DEFAULT_SUFFIX, request.node.name)) conn = Anonymous(topo.standalone).bind() # Allow write privilege to anyone useraccount = UserAccount(conn, USER_WITH_ACI_DELADD) @@ -115,22 +115,22 @@ def test_allow_write_privilege_to_anyone(topo, _add_user, aci_of_user): def test_allow_write_privilege_to_dynamic_group_with_scope_set_to_base_in_ldap_url( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): + """Modrdn Test 2 Allow write privilege to DYNAMIC_MODRDN group with scope set to base in LDAP URL + + :id: 4c0f8c00-7932-11e8-8398-8c16451d917b + :setup: server + :steps: + 1. Add test entry + 2. Add ACI + 3. User should follow ACI role + :expectedresults: + 1. Entry should be added + 2. Operation should succeed + 3. Operation should succeed """ - Modrdn Test 2 Allow write privilege to DYNAMIC_MODRDN group with scope set to base in LDAP URL - :id: 4c0f8c00-7932-11e8-8398-8c16451d917b - :setup: server - :steps: - 1. Add test entry - 2. Add ACI - 3. User should follow ACI role - :expectedresults: - 1. Entry should be added - 2. Operation should succeed - 3. Operation should succeed - """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(target = ldap:///{})(targetattr=*)(version 3.0; acl "$tet_thistest"; allow(all)(groupdn = "ldap:///{}"); )'.format(DEFAULT_SUFFIX, DYNAMIC_MODRDN)) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(target = ldap:///{})(targetattr="*")(version 3.0; acl "{}"; allow(all)(groupdn = "ldap:///{}"); )'.format(DEFAULT_SUFFIX, request.node.name, DYNAMIC_MODRDN)) conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) # Allow write privilege to DYNAMIC_MODRDN group with scope set to base in LDAP URL useraccount = UserAccount(conn, USER_DELADD) @@ -141,22 +141,22 @@ def test_allow_write_privilege_to_dynamic_group_with_scope_set_to_base_in_ldap_u assert 'cn=Jeff Vedder,ou=Product Development,dc=example,dc=com' == useraccount.dn -def test_write_access_to_naming_atributes(topo, _add_user, aci_of_user): - """ - Test for write access to naming atributes (1) - Test that check for add writes to the new naming attr - :id: 532fc630-7932-11e8-8924-8c16451d917b - :setup: server - :steps: - 1. Add test entry - 2. Add ACI - 3. User should follow ACI role - :expectedresults: - 1. Entry should be added - 2. Operation should succeed - 3. Operation should succeed +def test_write_access_to_naming_atributes(topo, _add_user, aci_of_user, request): + """Test for write access to naming atributes + Test that check for add writes to the new naming attr + + :id: 532fc630-7932-11e8-8924-8c16451d917b + :setup: server + :steps: + 1. Add test entry + 2. Add ACI + 3. User should follow ACI role + :expectedresults: + 1. Entry should be added + 2. Operation should succeed + 3. Operation should succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", '(target ="ldap:///{}")(targetattr != "uid")(version 3.0;acl "$tet_thistest";allow (write) (userdn = "ldap:///anyone");)'.format(DEFAULT_SUFFIX)) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", '(target ="ldap:///{}")(targetattr != "uid")(version 3.0;acl "{}";allow (write) (userdn = "ldap:///anyone");)'.format(DEFAULT_SUFFIX, request.node.name)) conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) #Test for write access to naming atributes useraccount = UserAccount(conn, USER_WITH_ACI_DELADD) @@ -164,23 +164,23 @@ def test_write_access_to_naming_atributes(topo, _add_user, aci_of_user): useraccount.rename("uid=Jeffbo Vedder") -def test_write_access_to_naming_atributes_two(topo, _add_user, aci_of_user): - """ - Test for write access to naming atributes (2) - :id: 5a2077d2-7932-11e8-9e7b-8c16451d917b - :setup: server - :steps: - 1. Add test entry - 2. Add ACI - 3. User should follow ACI role - 4. Now try to modrdn it to cn, won't work if request deleteoldrdn. - :expectedresults: - 1. Entry should be added - 2. Operation should succeed - 3. Operation should succeed - 4. Operation should not succeed +def test_write_access_to_naming_atributes_two(topo, _add_user, aci_of_user, request): + """Test for write access to naming atributes (2) + + :id: 5a2077d2-7932-11e8-9e7b-8c16451d917b + :setup: server + :steps: + 1. Add test entry + 2. Add ACI + 3. User should follow ACI role + 4. Now try to modrdn it to cn, won't work if request deleteoldrdn. + :expectedresults: + 1. Entry should be added + 2. Operation should succeed + 3. Operation should succeed + 4. Operation should not succeed """ - Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", '(target ="ldap:///{}")(targetattr != "uid")(version 3.0;acl "$tet_thistest";allow (write) (userdn = "ldap:///anyone");)'.format(DEFAULT_SUFFIX)) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", '(target ="ldap:///{}")(targetattr != "uid")(version 3.0;acl "{}";allow (write) (userdn = "ldap:///anyone");)'.format(DEFAULT_SUFFIX, request.node.name)) properties = { 'uid': 'Sam Carter1', 'cn': 'Sam Carter1', @@ -202,22 +202,22 @@ def test_write_access_to_naming_atributes_two(topo, _add_user, aci_of_user): @pytest.mark.bz950351 def test_access_aci_list_contains_any_deny_rule(topo, _add_user, aci_of_user): - """ - Testing bug #950351: RHDS denies MODRDN access if ACI list contains any DENY rule - Bug description: If you create a deny ACI for some or more attributes there is incorrect behaviour - as you cannot rename the entry anymore - :id: 62cbbb8a-7932-11e8-96a7-8c16451d917b - :setup: server - :steps: - 1. Add test entry - 2. Adding a new ou ou=People to $BASEDN - 3. Adding a user NEWENTRY9_MODRDN to ou=People,$BASEDN - 4. Adding an allow rule for NEWENTRY9_MODRDN and for others an aci deny rule - :expectedresults: - 1. Entry should be added - 2. Operation should succeed - 3. Operation should succeed - 4. Operation should succeed + """RHDS denies MODRDN access if ACI list contains any DENY rule + Bug description: If you create a deny ACI for some or more attributes there is incorrect behaviour + as you cannot rename the entry anymore + + :id: 62cbbb8a-7932-11e8-96a7-8c16451d917b + :setup: server + :steps: + 1. Add test entry + 2. Adding a new ou ou=People to $BASEDN + 3. Adding a user NEWENTRY9_MODRDN to ou=People,$BASEDN + 4. Adding an allow rule for NEWENTRY9_MODRDN and for others an aci deny rule + :expectedresults: + 1. Entry should be added + 2. Operation should succeed + 3. Operation should succeed + 4. Operation should succeed """ properties = { 'uid': 'NEWENTRY9_MODRDN', @@ -245,28 +245,28 @@ def test_access_aci_list_contains_any_deny_rule(topo, _add_user, aci_of_user): def test_renaming_target_entry(topo, _add_user, aci_of_user): - """ - Test for renaming target entry - :id: 6be1d33a-7932-11e8-9115-8c16451d917b - :setup: server - :steps: - 1. Add test entry - 2. Create a test user entry - 3.Create a new ou entry with an aci - 4. Make sure uid=$MYUID has the access - 5. Rename ou=OU0 to ou=OU1 - 6. Create another ou=OU2 - 7. Move ou=OU1 under ou=OU2 - 8. Make sure uid=$MYUID still has the access - :expectedresults: - 1. Entry should be added - 2. Operation should succeed - 3. Operation should succeed - 4. Operation should succeed - 5. Operation should succeed - 6. Operation should succeed - 7. Operation should succeed - 8. Operation should succeed + """Test for renaming target entry + + :id: 6be1d33a-7932-11e8-9115-8c16451d917b + :setup: server + :steps: + 1. Add test entry + 2. Create a test user entry + 3. Create a new ou entry with an aci + 4. Make sure uid=$MYUID has the access + 5. Rename ou=OU0 to ou=OU1 + 6. Create another ou=OU2 + 7. Move ou=OU1 under ou=OU2 + 8. Make sure uid=$MYUID still has the access + :expectedresults: + 1. Entry should be added + 2. Operation should succeed + 3. Operation should succeed + 4. Operation should succeed + 5. Operation should succeed + 6. Operation should succeed + 7. Operation should succeed + 8. Operation should succeed """ properties = { 'uid': 'TRAC340_MODRDN', @@ -281,7 +281,7 @@ def test_renaming_target_entry(topo, _add_user, aci_of_user): user.set("userPassword", "password") ou = OrganizationalUnit(topo.standalone, 'ou=OU0,{}'.format(DEFAULT_SUFFIX)) ou.create(properties={'ou': 'OU0'}) - ou.set('aci', '(targetattr=*)(version 3.0; acl "$MYUID";allow(read, search, compare) userdn = "ldap:///{}";)'.format(TRAC340_MODRDN)) + ou.set('aci', '(targetattr="*")(version 3.0; acl "$MYUID";allow(read, search, compare) userdn = "ldap:///{}";)'.format(TRAC340_MODRDN)) conn = UserAccount(topo.standalone, TRAC340_MODRDN).bind(PW_DM) assert OrganizationalUnits(conn, DEFAULT_SUFFIX).get('OU0') # Test for renaming target entry diff --git a/dirsrvtests/tests/suites/acl/roledn_test.py b/dirsrvtests/tests/suites/acl/roledn_test.py index 227ebd95f..6ccd652cf 100644 --- a/dirsrvtests/tests/suites/acl/roledn_test.py +++ b/dirsrvtests/tests/suites/acl/roledn_test.py @@ -78,10 +78,10 @@ def _add_user(request, topo): f'(target="ldap:///{OR_RULE_ACCESS}")(targetattr="*")' f'(version 3.0; aci "or role aci"; allow(all) ' f'roledn = "ldap:///{ROLE1} || ldap:///{ROLE21}";)', - f'(target="ldap:///{ALL_ACCESS}")(targetattr=*)' + f'(target="ldap:///{ALL_ACCESS}")(targetattr="*")' f'(version 3.0; aci "anyone role aci"; allow(all) ' f'roledn = "ldap:///anyone";)', - f'(target="ldap:///{NOT_RULE_ACCESS}")(targetattr=*)' + f'(target="ldap:///{NOT_RULE_ACCESS}")(targetattr="*")' f'(version 3.0; aci "not role aci"; allow(all)' f'roledn != "ldap:///{ROLE1} || ldap:///{ROLE21}";)']) diff --git a/dirsrvtests/tests/suites/acl/selfdn_permissions_test.py b/dirsrvtests/tests/suites/acl/selfdn_permissions_test.py index af7501338..dd506a786 100644 --- a/dirsrvtests/tests/suites/acl/selfdn_permissions_test.py +++ b/dirsrvtests/tests/suites/acl/selfdn_permissions_test.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2016 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -90,8 +90,8 @@ def test_selfdn_permission_add(topology_st, allow_user_init): :id: e837a9ef-be92-48da-ad8b-ebf42b0fede1 :setup: Standalone instance, add a entry which is used to bind, - enable acl error logging by setting 'nsslapd-errorlog-level' to '128', - remove aci's to start with a clean slate, and add dummy entries + enable acl error logging by setting 'nsslapd-errorlog-level' to '128', + remove aci's to start with a clean slate, and add dummy entries :steps: 1. Check we can not ADD an entry without the proper SELFDN aci 2. Check with the proper ACI we can not ADD with 'member' attribute @@ -191,8 +191,8 @@ def test_selfdn_permission_search(topology_st, allow_user_init): :id: 06d51ef9-c675-4583-99b2-4852dbda190e :setup: Standalone instance, add a entry which is used to bind, - enable acl error logging by setting 'nsslapd-errorlog-level' to '128', - remove aci's to start with a clean slate, and add dummy entries + enable acl error logging by setting 'nsslapd-errorlog-level' to '128', + remove aci's to start with a clean slate, and add dummy entries :steps: 1. Check we can not search an entry without the proper SELFDN aci 2. Add proper ACI @@ -217,7 +217,7 @@ def test_selfdn_permission_search(topology_st, allow_user_init): topology_st.standalone.simple_bind_s(DN_DM, PASSWORD) ACI_TARGET = "(target = \"ldap:///cn=*,%s\")" % SUFFIX - ACI_TARGETATTR = "(targetattr = *)" + ACI_TARGETATTR = '(targetattr="*")' ACI_TARGETFILTER = "(targetfilter =\"(objectClass=%s)\")" % OC_NAME ACI_ALLOW = "(version 3.0; acl \"SelfDN search-read\"; allow (read, search, compare)" ACI_SUBJECT = " userattr = \"member#selfDN\";)" @@ -241,8 +241,8 @@ def test_selfdn_permission_modify(topology_st, allow_user_init): :id: 97a58844-095f-44b0-9029-dd29a7d83d68 :setup: Standalone instance, add a entry which is used to bind, - enable acl error logging by setting 'nsslapd-errorlog-level' to '128', - remove aci's to start with a clean slate, and add dummy entries + enable acl error logging by setting 'nsslapd-errorlog-level' to '128', + remove aci's to start with a clean slate, and add dummy entries :steps: 1. Check we can not modify an entry without the proper SELFDN aci 2. Add proper ACI @@ -272,7 +272,7 @@ def test_selfdn_permission_modify(topology_st, allow_user_init): topology_st.standalone.simple_bind_s(DN_DM, PASSWORD) ACI_TARGET = "(target = \"ldap:///cn=*,%s\")" % SUFFIX - ACI_TARGETATTR = "(targetattr = *)" + ACI_TARGETATTR = '(targetattr="*")' ACI_TARGETFILTER = "(targetfilter =\"(objectClass=%s)\")" % OC_NAME ACI_ALLOW = "(version 3.0; acl \"SelfDN write\"; allow (write)" ACI_SUBJECT = " userattr = \"member#selfDN\";)" @@ -300,8 +300,8 @@ def test_selfdn_permission_delete(topology_st, allow_user_init): :id: 0ec4c0ec-e7b0-4ef1-8373-ab25aae34516 :setup: Standalone instance, add a entry which is used to bind, - enable acl error logging by setting 'nsslapd-errorlog-level' to '128', - remove aci's to start with a clean slate, and add dummy entries + enable acl error logging by setting 'nsslapd-errorlog-level' to '128', + remove aci's to start with a clean slate, and add dummy entries :steps: 1. Check we can not delete an entry without the proper SELFDN aci 2. Add proper ACI @@ -309,6 +309,7 @@ def test_selfdn_permission_delete(topology_st, allow_user_init): :expectedresults: 1. Operation should be successful 2. Operation should be successful + 3. Operation should be successful """ topology_st.standalone.log.info("\n\n######################### DELETE ######################\n") diff --git a/dirsrvtests/tests/suites/acl/syntax_test.py b/dirsrvtests/tests/suites/acl/syntax_test.py index c143ff7c9..b8f27480a 100644 --- a/dirsrvtests/tests/suites/acl/syntax_test.py +++ b/dirsrvtests/tests/suites/acl/syntax_test.py @@ -1,12 +1,10 @@ -""" # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2019 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). # See LICENSE for details. # --- END COPYRIGHT BLOCK ---- -""" import os import pytest @@ -74,66 +72,66 @@ INVALID = [('test_targattrfilters_1', f'(version 3.0; acl "Name of the ACI"; deny absolute (all)userdn="ldap:///anyone";)'), ('test_targattrfilters_19', f'(target = ldap:///cn=Jeff Vedder,ou=Product Development,{DEFAULT_SUFFIX})' - f'(targetattr=*)' + f'(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny(write)gropdn="ldap:///anyone";)'), ('test_targattrfilters_21', f'(target = ldap:///cn=Jeff Vedder,ou=Product Development,{DEFAULT_SUFFIX})' - f'(targetattr=*)' + f'(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny(rite)userdn="ldap:///anyone";)'), ('test_targattrfilters_22', f'(targt = ldap:///cn=Jeff Vedder,ou=Product Development,{DEFAULT_SUFFIX})' - f'(targetattr=*)' + f'(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute (all)userdn="ldap:///anyone";)'), ('test_targattrfilters_23', f'(target = ldap:///cn=Jeff Vedder,ou=Product Development,{DEFAULT_SUFFIX})' - f'(targetattr=*)' + f'(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; absolute (all)userdn="ldap:///anyone";)'), ('test_Missing_acl_mispel', f'(target = ldap:///cn=Jeff Vedder,ou=Product Development,{DEFAULT_SUFFIX})' - f'(targetattr=*)' + f'(targetattr="*")' f'(version 3.0; alc "Name of the ACI"; deny absolute (all)userdn="ldap:///anyone";)'), ('test_Missing_acl_string', f'(target = ldap:///cn=Jeff Vedder,ou=Product Development,{DEFAULT_SUFFIX})' - f'(targetattr=*)' + f'(targetattr="*")' f'(version 3.0; "Name of the ACI"; deny absolute (all)userdn="ldap:///anyone";)'), ('test_Wrong_version_string', f'(target = ldap:///cn=Jeff Vedder,ou=Product Development,{DEFAULT_SUFFIX})' - f'(targetattr=*)' + f'(targetattr="*")' f'(version 2.0; acl "Name of the ACI"; deny absolute (all)userdn="ldap:///anyone";)'), ('test_Missing_version_string', f'(target = ldap:///cn=Jeff Vedder,ou=Product Development,{DEFAULT_SUFFIX})' - f'(targetattr=*)' + f'(targetattr="*")' f'(; acl "Name of the ACI"; deny absolute (all)userdn="ldap:///anyone";)'), ('test_Authenticate_statement', f'(target = ldap:///cn=Jeff Vedder,ou=Product Development,{DEFAULT_SUFFIX})' f'(targetattr != "uid")' - f'(targetattr=*)(version 3.0; acl "Name of the ACI"; deny absolute (all)' + f'(targetattr="*")(version 3.0; acl "Name of the ACI"; deny absolute (all)' f'userdn="ldap:///anyone";)'), ('test_Multiple_targets', f'(target = ldap:///ou=Product Development,{DEFAULT_SUFFIX})' - f'(target = ldap:///ou=Product Testing,{DEFAULT_SUFFIX})(targetattr=*)' + f'(target = ldap:///ou=Product Testing,{DEFAULT_SUFFIX})(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute (all)userdn="ldap:///anyone";)'), ('test_Target_set_to_self', - f'(target = ldap:///self)(targetattr=*)' + f'(target = ldap:///self)(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute (all)userdn="ldap:///anyone";)'), ('test_target_set_with_ldap_instead_of_ldap', - f'(target = ldap:\\\{DEFAULT_SUFFIX})(targetattr=*)' + f'(target = ldap:\\\{DEFAULT_SUFFIX})(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute (all)userdn="ldap:///anyone";)'), ('test_target_set_with_more_than_three', - f'(target = ldap:////{DEFAULT_SUFFIX})(targetattr=*)' + f'(target = ldap:////{DEFAULT_SUFFIX})(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute (all)userdn="ldap:///anyone";)'), ('test_target_set_with_less_than_three', - f'(target = ldap://{DEFAULT_SUFFIX})(targetattr=*)' + f'(target = ldap://{DEFAULT_SUFFIX})(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute (all)userdn="ldap:///anyone";)'), ('test_bind_rule_set_with_less_than_three', - f'(target = ldap:///{DEFAULT_SUFFIX})(targetattr=*)' + f'(target = ldap:///{DEFAULT_SUFFIX})(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute (all)userdn="ldap:/anyone";)'), ('test_Use_semicolon_instead_of_comma_in_permission', - f'(target = ldap:///{DEFAULT_SUFFIX})(targetattr=*)' + f'(target = ldap:///{DEFAULT_SUFFIX})(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny ' f'(read; search; compare; write)userdn="ldap:///anyone";)'), ('test_Use_double_equal_instead_of_equal_in_the_target', - f'(target == ldap:///{DEFAULT_SUFFIX})(targetattr=*)' + f'(target == ldap:///{DEFAULT_SUFFIX})(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute (all)userdn="ldap:///anyone";)'), ('test_use_double_equal_instead_of_equal_in_user_and_group_access', f'(target = ldap:///{DEFAULT_SUFFIX})' @@ -143,21 +141,21 @@ INVALID = [('test_targattrfilters_1', f'(target = ldap:///{DEFAULT_SUFFIX})' f'(version 3.0; acl Name of the ACI ; deny absolute (all)userdn = "ldap:///anyone";)'), ('test_extra_parentheses_case_1', - f'( )(target = ldap:///{DEFAULT_SUFFIX}) (targetattr=*)' + f'( )(target = ldap:///{DEFAULT_SUFFIX}) (targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute (all)userdn = "ldap:///anyone";)'), ('test_extra_parentheses_case_2', - f'(((((target = ldap:///{DEFAULT_SUFFIX})(targetattr=*)' + f'(((((target = ldap:///{DEFAULT_SUFFIX})(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute (all)' f'userdn == "ldap:///anyone";)'), ('test_extra_parentheses_case_3', - f'(((target = ldap:///{DEFAULT_SUFFIX}) (targetattr=*)' + f'(((target = ldap:///{DEFAULT_SUFFIX}) (targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute ' f'(all)userdn = "ldap:///anyone";)))'), ('test_no_semicolon_at_the_end_of_the_aci', - f'(target = ldap:///{DEFAULT_SUFFIX}) (targetattr=*)' + f'(target = ldap:///{DEFAULT_SUFFIX}) (targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute (all)userdn = "ldap:///anyone")'), ('test_a_character_different_of_a_semicolon_at_the_end_of_the_aci', - f'(target = ldap:///{DEFAULT_SUFFIX}) (targetattr=*)' + f'(target = ldap:///{DEFAULT_SUFFIX}) (targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute (all)userdn = "ldap:///anyone"%)'), ('test_bad_filter', f'(target = ldap:///{DEFAULT_SUFFIX}) ' @@ -173,14 +171,14 @@ INVALID = [('test_targattrfilters_1', FAILED = [('test_targattrfilters_18', f'(target = ldap:///cn=Jeff Vedder,ou=Product Development,{DEFAULT_SUFFIX})' - f'(targetattr=*)' + f'(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny(write)userdn="ldap:///{"123" * 300}";)'), ('test_targattrfilters_20', f'(target = ldap:///cn=Jeff Vedder,ou=Product Development,{DEFAULT_SUFFIX})' - f'(targetattr=*)' + f'(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny(write)userdns="ldap:///anyone";)'), ('test_bind_rule_set_with_more_than_three', - f'(target = ldap:///{DEFAULT_SUFFIX})(targetattr=*)' + f'(target = ldap:///{DEFAULT_SUFFIX})(targetattr="*")' f'(version 3.0; acl "Name of the ACI"; deny absolute (all)' f'userdn="ldap:////////anyone";)'), ('test_Use_double_equal_instead_of_equal_in_the_targetattr', @@ -253,7 +251,7 @@ def test_target_set_above_the_entry_test(topo): domain = Domain(topo.standalone, "ou=People,{}".format(DEFAULT_SUFFIX)) with pytest.raises(ldap.INVALID_SYNTAX): domain.add("aci", f'(target = ldap:///{DEFAULT_SUFFIX})' - f'(targetattr=*)(version 3.0; acl "Name of the ACI"; deny absolute ' + f'(targetattr="*")(version 3.0; acl "Name of the ACI"; deny absolute ' f'(all)userdn="ldap:///anyone";)') diff --git a/dirsrvtests/tests/suites/acl/userattr_test.py b/dirsrvtests/tests/suites/acl/userattr_test.py index 542d7afc9..3a13d32dc 100644 --- a/dirsrvtests/tests/suites/acl/userattr_test.py +++ b/dirsrvtests/tests/suites/acl/userattr_test.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2019 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -55,7 +55,7 @@ def _add_user(topo): """ This function will create user for the test and in the end entries will be deleted . """ - role_aci_body = '(targetattr=*)(version 3.0; aci "role aci"; allow(all)' + role_aci_body = '(targetattr="*")(version 3.0; aci "role aci"; allow(all)' # Creating OUs ous = OrganizationalUnits(topo.standalone, DEFAULT_SUFFIX) ou_accounting = ous.create(properties={'ou': 'Accounting'}) @@ -77,7 +77,7 @@ def _add_user(topo): 'description': LEVEL_1, 'businessCategory': LEVEL_0}) - inheritance_aci_body = '(targetattr=*)(version 3.0; aci "Inheritance aci"; allow(all) ' + inheritance_aci_body = '(targetattr="*")(version 3.0; aci "Inheritance aci"; allow(all) ' ou_inheritance.set('aci', [f'{inheritance_aci_body} ' f'userattr = "parent[0].businessCategory#USERDN";)', f'{inheritance_aci_body} ' diff --git a/dirsrvtests/tests/suites/acl/valueacl_part2_test.py b/dirsrvtests/tests/suites/acl/valueacl_part2_test.py index 5f5b1c64e..763c0b5a2 100644 --- a/dirsrvtests/tests/suites/acl/valueacl_part2_test.py +++ b/dirsrvtests/tests/suites/acl/valueacl_part2_test.py @@ -28,6 +28,17 @@ HUMAN_OU_GLOBAL = "ou=Human Resources,{}".format(DEFAULT_SUFFIX) @pytest.fixture(scope="function") def aci_of_user(request, topo): + # Add anonymous access aci + ACI_TARGET = "(targetattr != \"userpassword\")(target = \"ldap:///%s\")" % (DEFAULT_SUFFIX) + ACI_ALLOW = "(version 3.0; acl \"Anonymous Read access\"; allow (read,search,compare)" + ACI_SUBJECT = "(userdn=\"ldap:///anyone\");)" + ANON_ACI = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT + suffix = Domain(topo.standalone, DEFAULT_SUFFIX) + try: + suffix.add('aci', ANON_ACI) + except ldap.TYPE_OR_VALUE_EXISTS: + pass + aci_list = Domain(topo.standalone, DEFAULT_SUFFIX).get_attr_vals('aci') def finofaci(): @@ -107,10 +118,10 @@ def _add_user(request, topo): request.addfinalizer(fin) -def test_we_can_search_as_expected(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) +def test_we_can_search_as_expected(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that we can search as expected + :id: e845dbba-7aa9-11e8-8988-8c16451d917b :setup: server :steps: @@ -124,8 +135,8 @@ def test_we_can_search_as_expected(topo, _add_user, aci_of_user): """ ACI_BODY = '(target="ldap:///cn=*,ou=Product Development, {}")' \ '(targetfilter="cn=Jeff*")(targetattr="secretary || objectclass || mail")' \ - '(targattrfilters = "add=title:(title=arch*)")(version 3.0; acl "$tet_thistest"; ' \ - 'allow (write,read,search,compare) (userdn = "ldap:///anyone") ;)'.format(DEFAULT_SUFFIX) + '(targattrfilters = "add=title:(title=arch*)")(version 3.0; acl "{}"; ' \ + 'allow (write,read,search,compare) (userdn = "ldap:///anyone") ;)'.format(DEFAULT_SUFFIX, request.node.name) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) conn = Anonymous(topo.standalone).bind() # aci will allow secretary , mail , objectclass @@ -135,11 +146,11 @@ def test_we_can_search_as_expected(topo, _add_user, aci_of_user): assert user.get_attr_vals('objectclass') -def test_we_can_mod_title_as_expected(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the +def test_we_can_mod_title_as_expected(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) - "Valueacl Test $tet_thistest Test search will work with targattrfilters present." + Test search will work with targattrfilters present. + :id: f8c1ea88-7aa9-11e8-a55c-8c16451d917b :setup: server :steps: @@ -153,8 +164,8 @@ def test_we_can_mod_title_as_expected(topo, _add_user, aci_of_user): """ ACI_BODY = '(target="ldap:///cn=*,ou=Product Development, {}")' \ '(targetfilter="cn=Jeff*")(targetattr="secretary || objectclass || mail")' \ - '(targattrfilters = "add=title:(title=arch*)")(version 3.0; acl "$tet_thistest"; ' \ - 'allow (write,read,search,compare) (userdn = "ldap:///anyone") ;)'.format(DEFAULT_SUFFIX) + '(targattrfilters = "add=title:(title=arch*)")(version 3.0; acl "{}"; ' \ + 'allow (write,read,search,compare) (userdn = "ldap:///anyone") ;)'.format(DEFAULT_SUFFIX, request.node.name) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) # aci will not allow 'title', 'topdog' conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) @@ -163,11 +174,11 @@ def test_we_can_mod_title_as_expected(topo, _add_user, aci_of_user): user.add('title', 'topdog') -def test_modify_with_multiple_filters(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the +def test_modify_with_multiple_filters(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) - "Valueacl Test $tet_thistest Allowed by multiple." + Allowed by multiple filters + :id: fd9d223e-7aa9-11e8-a83b-8c16451d917b :setup: server :steps: @@ -181,9 +192,9 @@ def test_modify_with_multiple_filters(topo, _add_user, aci_of_user): """ ACI_BODY = '(targattrfilters = "add=title:(title=architect) && secretary:' \ '(secretary=cn=Meylan,{}), del=title:(title=architect) && secretary:' \ - '(secretary=cn=Meylan,{})")(version 3.0; acl "$tet_thistest"; allow (write) ' \ + '(secretary=cn=Meylan,{})")(version 3.0; acl "{}"; allow (write) ' \ '(userdn = "ldap:///anyone") ;)'.format( - DEFAULT_SUFFIX, DEFAULT_SUFFIX + DEFAULT_SUFFIX, DEFAULT_SUFFIX, request.node.name ) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) @@ -195,11 +206,11 @@ def test_modify_with_multiple_filters(topo, _add_user, aci_of_user): assert user.get_attr_val('secretary') -def test_denied_by_multiple_filters(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the value of the +def test_denied_by_multiple_filters(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) - "Valueacl Test $tet_thistest Denied by multiple filters." + Denied by multiple filters + :id: 034c6c62-7aaa-11e8-8634-8c16451d917b :setup: server :steps: @@ -213,8 +224,8 @@ def test_denied_by_multiple_filters(topo, _add_user, aci_of_user): """ ACI_BODY = '(targattrfilters = "add=title:(title=architect) && secretary:' \ '(secretary=cn=Meylan,{}), del=title:(title=architect) && secretary:' \ - '(secretary=cn=Meylan,{})")(version 3.0; acl "$tet_thistest"; allow (write) ' \ - '(userdn = "ldap:///anyone") ;)'.format(DEFAULT_SUFFIX, DEFAULT_SUFFIX) + '(secretary=cn=Meylan,{})")(version 3.0; acl "{}"; allow (write) ' \ + '(userdn = "ldap:///anyone") ;)'.format(DEFAULT_SUFFIX, DEFAULT_SUFFIX, request.node.name) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) # aci will allow title some attribute only @@ -228,11 +239,11 @@ def test_denied_by_multiple_filters(topo, _add_user, aci_of_user): user.add("secretary", "cn=Grenoble,dc=example,dc=com") -def test_allowed_add_one_attribute(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the value of the +def test_allowed_add_one_attribute(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) - "Valueacl Test $tet_thistest Allowed add one attribute (in presence of multiple filters)" + Allowed add one attribute (in presence of multiple filters) + :id: 086c7f0c-7aaa-11e8-b69f-8c16451d917b :setup: server :steps: @@ -245,9 +256,9 @@ def test_allowed_add_one_attribute(topo, _add_user, aci_of_user): 3. Operation should succeed """ ACI_BODY = '(targattrfilters = "add=title:(title=architect) && secretary:(secretary=cn=Meylan, {}), ' \ - 'del=title:(title=architect) && secretary:(secretary=cn=Meylan, {})")(version 3.0; acl "$tet_thistest"; ' \ + 'del=title:(title=architect) && secretary:(secretary=cn=Meylan, {})")(version 3.0; acl "{}"; ' \ 'allow (write) (userdn = "ldap:///{}") ;)'.format( - DEFAULT_SUFFIX, DEFAULT_SUFFIX, USER_WITH_ACI_DELADD) + DEFAULT_SUFFIX, DEFAULT_SUFFIX, request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) user = UserAccount(conn, USER_DELADD) @@ -258,12 +269,12 @@ def test_allowed_add_one_attribute(topo, _add_user, aci_of_user): def test_cannot_add_an_entry_with_attribute_values_we_are_not_allowed_add( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): - """ - Testing the targattrfilters keyword that allows access control based on the value of the + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) - "Valueacl Test $tet_thistest Test not allowed add an entry" + Test not allowed add an entry + :id: 0d0effee-7aaa-11e8-b673-8c16451d917b :setup: server :steps: @@ -277,8 +288,8 @@ def test_cannot_add_an_entry_with_attribute_values_we_are_not_allowed_add( """ ACI_BODY = '(targattrfilters = "add=title:(|(title=engineer)(title=cool dude)(title=scum)) ' \ '&& secretary:(secretary=cn=Meylan, {}), del=title:(|(title=engineer)(title=cool dude)' \ - '(title=scum))")(version 3.0; aci "$tet_thistest"; allow (add) userdn = "ldap:///{}";)'.format( - DEFAULT_SUFFIX, DEFAULT_SUFFIX) + '(title=scum))")(version 3.0; aci "{}"; allow (add) userdn = "ldap:///{}";)'.format( + DEFAULT_SUFFIX, request.node.name, DEFAULT_SUFFIX) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) properties = { 'uid': 'FRED', @@ -298,11 +309,11 @@ def test_cannot_add_an_entry_with_attribute_values_we_are_not_allowed_add( user.add("objectclass", "person") -def test_on_modrdn(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the value of the +def test_on_modrdn(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that valuacls kick in for modrdn operation. + :id: 12985dde-7aaa-11e8-abde-8c16451d917b :setup: server :steps: @@ -315,8 +326,8 @@ def test_on_modrdn(topo, _add_user, aci_of_user): 3. Operation should succeed """ ACI_BODY = '(target="ldap:///cn=*,ou=Accounting,{}")(targattrfilters = "add=cn:(|(cn=engineer)), ' \ - 'del=title:(|(title=engineer)(title=cool dude)(title=scum))")(version 3.0; aci "$tet_thistest"; ' \ - 'allow (write) userdn = "ldap:///{}";)'.format(DEFAULT_SUFFIX, USER_WITH_ACI_DELADD) + 'del=title:(|(title=engineer)(title=cool dude)(title=scum))")(version 3.0; aci "{}"; ' \ + 'allow (write) userdn = "ldap:///{}";)'.format(DEFAULT_SUFFIX, request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) # modrdn_s is not allowed with ou=OU1 @@ -325,11 +336,11 @@ def test_on_modrdn(topo, _add_user, aci_of_user): useraccount.rename("ou=OU1") -def test_on_modrdn_allow(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the value of the attributes being +def test_on_modrdn_allow(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) - "Valueacl Test $tet_thistest Test modrdn still works (2)" + Test modrdn still works (2) + :id: 17720562-7aaa-11e8-82ee-8c16451d917b :setup: server :steps: @@ -342,8 +353,8 @@ def test_on_modrdn_allow(topo, _add_user, aci_of_user): 3. Operation should succeed """ ACI_BODY = '(target="ldap:///{}")(targattrfilters = "add=cn:((cn=engineer)), del=cn:((cn=jonny))")' \ - '(version 3.0; aci "$tet_thistest"; allow (write) ' \ - 'userdn = "ldap:///{}";)'.format(DEFAULT_SUFFIX, USER_WITH_ACI_DELADD) + '(version 3.0; aci "{}"; allow (write) ' \ + 'userdn = "ldap:///{}";)'.format(DEFAULT_SUFFIX, request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) properties = { 'uid': 'jonny', @@ -364,12 +375,12 @@ def test_on_modrdn_allow(topo, _add_user, aci_of_user): @pytest.mark.bz979515 def test_targattrfilters_keyword(topo): - """ - Testing the targattrfilters keyword that allows access control based on the value + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) "Bug #979515 - ACLs inoperative in some search scenarios [rhel-6.5]" "Bug #979516 is a clone for DS8.2 on RHEL5.9" "Bug #979514 is a clone for RHEL6.4 zStream errata" + :id: 23f9e9d0-7aaa-11e8-b16b-8c16451d917b :setup: server :steps: diff --git a/dirsrvtests/tests/suites/acl/valueacl_test.py b/dirsrvtests/tests/suites/acl/valueacl_test.py index 54bc13452..3bbbdcabb 100644 --- a/dirsrvtests/tests/suites/acl/valueacl_test.py +++ b/dirsrvtests/tests/suites/acl/valueacl_test.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2019 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -28,6 +28,17 @@ HUMAN_OU_GLOBAL = "ou=Human Resources,{}".format(DEFAULT_SUFFIX) @pytest.fixture(scope="function") def aci_of_user(request, topo): + # Add anonymous access aci + ACI_TARGET = "(targetattr != \"userpassword\")(target = \"ldap:///%s\")" % (DEFAULT_SUFFIX) + ACI_ALLOW = "(version 3.0; acl \"Anonymous Read access\"; allow (read,search,compare)" + ACI_SUBJECT = "(userdn=\"ldap:///anyone\");)" + ANON_ACI = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT + suffix = Domain(topo.standalone, DEFAULT_SUFFIX) + try: + suffix.add('aci', ANON_ACI) + except ldap.TYPE_OR_VALUE_EXISTS: + pass + aci_list = Domain(topo.standalone, DEFAULT_SUFFIX).get_attr_vals('aci') def finofaci(): @@ -167,10 +178,10 @@ class _AddFREDWithRoot: def test_delete_an_attribute_value_we_are_not_allowed_to_delete( topo, _add_user, aci_of_user ): - """ - Testing the targattrfilters keyword that allows access control based on the value + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that we can MODIFY:add an attribute value we are allowed to add + :id: 7c41baa6-7aa9-11e8-9bdc-8c16451d917b :setup: server :steps: @@ -192,12 +203,12 @@ def test_delete_an_attribute_value_we_are_not_allowed_to_delete( def test_donot_allow_write_access_to_title_if_value_is_not_architect( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): - """ - Testing the targattrfilters keyword that allows access control based on the value of the + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that we cannot MODIFY:add an attribute value we are not allowed to add + :id: 822c607e-7aa9-11e8-b2e7-8c16451d917b :setup: server :steps: @@ -210,7 +221,7 @@ def test_donot_allow_write_access_to_title_if_value_is_not_architect( 3. Operation should succeed """ ACI_BODY = '(targattrfilters = "add=title:(title=architect), del=title:(title=architect)")' \ - '(version 3.0; acl "$tet_thistest"; allow (write) (userdn = "ldap:///{}") ;)'.format(USER_WITH_ACI_DELADD) + '(version 3.0; acl "{}"; allow (write) (userdn = "ldap:///{}") ;)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) # aci will allow to add title architect conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) @@ -221,12 +232,12 @@ def test_donot_allow_write_access_to_title_if_value_is_not_architect( def test_delete_an_attribute_value_we_are_allowed_to_delete( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): - """ - Testing the targattrfilters keyword that allows access control based on the value of + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) - Test that we can MODIFY:delete an attribute value we are allowed to delete, + Test that we can MODIFY:delete an attribute value we are allowed to delete + :id: 86f36b34-7aa9-11e8-ab16-8c16451d917b :setup: server :steps: @@ -239,7 +250,7 @@ def test_delete_an_attribute_value_we_are_allowed_to_delete( 3. Operation should succeed """ ACI_BODY = '(targattrfilters = "add=title:(title=architect), del=title:(title=architect)")' \ - '(version 3.0; acl "$tet_thistest"; allow (write) (userdn = "ldap:///{}") ;)'.format(USER_WITH_ACI_DELADD) + '(version 3.0; acl "{}"; allow (write) (userdn = "ldap:///{}") ;)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) _AddTitleWithRoot(topo, "architect").add() # aci will allow to delete title architect @@ -249,12 +260,12 @@ def test_delete_an_attribute_value_we_are_allowed_to_delete( def test_delete_an_attribute_value_we_are_not_allowed_to_deleted( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): - """ - Testing the targattrfilters keyword that allows access control based on the value of the + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) - Test that we cannot MODIFY:delete an attribute value we are allowed to delete, + Test that we cannot MODIFY:delete an attribute value we are allowed to delete + :id: 8c9f3a90-7aa9-11e8-bf2e-8c16451d917b :setup: server :steps: @@ -267,7 +278,7 @@ def test_delete_an_attribute_value_we_are_not_allowed_to_deleted( 3. Operation should succeed """ ACI_BODY = '(targattrfilters = "add=title:(title=architect), del=title:(title=architect)")' \ - '(version 3.0; acl "$tet_thistest"; allow (write) (userdn = "ldap:///{}") ;)'.format(USER_WITH_ACI_DELADD) + '(version 3.0; acl "{}"; allow (write) (userdn = "ldap:///{}") ;)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) _AddTitleWithRoot(topo, "engineer").add() # acl will not allow to delete title engineer @@ -276,11 +287,11 @@ def test_delete_an_attribute_value_we_are_not_allowed_to_deleted( _ModTitleArchitectJeffVedder(topo, "engineer", conn).delete() -def test_allow_modify_replace(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the value of the +def test_allow_modify_replace(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that we can MODIFY:replace an attribute if we have correct add/delete rights. + :id: 9148a234-7aa9-11e8-a1f1-8c16451d917b :setup: server :steps: @@ -293,8 +304,8 @@ def test_allow_modify_replace(topo, _add_user, aci_of_user): 3. Operation should succeed """ ACI_BODY = '(targattrfilters = "add=title:(title=engineer), del=title:(|(title=architect)' \ - '(title=idiot))")(version 3.0; acl "$tet_thistest"; ' \ - 'allow (write) (userdn = "ldap:///{}") ;)'.format(USER_WITH_ACI_DELADD) + '(title=idiot))")(version 3.0; acl "{}"; ' \ + 'allow (write) (userdn = "ldap:///{}") ;)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) _AddTitleWithRoot(topo, "architect").add() _AddTitleWithRoot(topo, "idiot").add() @@ -305,11 +316,11 @@ def test_allow_modify_replace(topo, _add_user, aci_of_user): _ModTitleArchitectJeffVedder(topo, "engineer", conn).delete() -def test_allow_modify_delete(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the value of the +def test_allow_modify_delete(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) - "Valueacl Test $tet_thistest Don't Allow modify:replace because of lack of delete rights" + Don't Allow modify:replace because of lack of delete rights + :id: 962842d2-7aa9-11e8-b39e-8c16451d917b :setup: server :steps: @@ -322,8 +333,8 @@ def test_allow_modify_delete(topo, _add_user, aci_of_user): 3. Operation should succeed """ ACI_BODY = '(targattrfilters = "add=title:(title=engineer), del=title:(|(title=architect))")' \ - '(version 3.0; acl "$tet_thistest"; allow (write) ' \ - '(userdn = "ldap:///{}") ;)'.format(USER_WITH_ACI_DELADD) + '(version 3.0; acl "{}"; allow (write) ' \ + '(userdn = "ldap:///{}") ;)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) _AddTitleWithRoot(topo, "architect").add() _AddTitleWithRoot(topo, "idiot").add() @@ -335,11 +346,11 @@ def test_allow_modify_delete(topo, _add_user, aci_of_user): _ModTitleArchitectJeffVedder(topo, "idiot", conn).delete() -def test_replace_an_attribute_if_we_lack(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the value of the +def test_replace_an_attribute_if_we_lack(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that we cannot MODIFY:replace an attribute if we lack + :id: 9b1e6afa-7aa9-11e8-ac5b-8c16451d917b :setup: server :steps: @@ -352,8 +363,8 @@ def test_replace_an_attribute_if_we_lack(topo, _add_user, aci_of_user): 3. Operation should succeed """ ACI_BODY = '(targattrfilters = "add=title:(title=engineer), del=title:(|(title=architect))")' \ - '(version 3.0; acl "$tet_thistest"; allow (write) ' \ - '(userdn = "ldap:///{}") ;)'.format(USER_WITH_ACI_DELADD) + '(version 3.0; acl "{}"; allow (write) ' \ + '(userdn = "ldap:///{}") ;)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) _AddTitleWithRoot(topo, "architect").add() _AddTitleWithRoot(topo, "idiot").add() @@ -365,13 +376,13 @@ def test_replace_an_attribute_if_we_lack(topo, _add_user, aci_of_user): def test_remove_an_attribute_if_we_have_del_rights_to_all_attr_value( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): - """ - Testing the targattrfilters keyword that allows access control based on the value of the - attributes being added (or deleted)) + """Testing the targattrfilters keyword that allows access control based on the value of the + attributes being added (or deleted)) Test that we can use MODIFY:delete to entirely remove an attribute if we have del rights to all attr values negative case tested next. + :id: a0c9e0c4-7aa9-11e8-8880-8c16451d917b :setup: server :steps: @@ -384,8 +395,8 @@ def test_remove_an_attribute_if_we_have_del_rights_to_all_attr_value( 3. Operation should succeed """ ACI_BODY = '(targattrfilters = "add=title:(title=engineer), del=title:(|(title=architect)' \ - '(title=idiot))")(version 3.0; acl "$tet_thistest"; allow (write)' \ - ' (userdn = "ldap:///{}") ;)'.format(USER_WITH_ACI_DELADD) + '(title=idiot))")(version 3.0; acl "{}"; allow (write)' \ + ' (userdn = "ldap:///{}") ;)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) _AddTitleWithRoot(topo, "architect").add() _AddTitleWithRoot(topo, "idiot").add() @@ -395,13 +406,13 @@ def test_remove_an_attribute_if_we_have_del_rights_to_all_attr_value( def test_remove_an_attribute_if_we_donot_have_del_rights_to_all_attr_value( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): - """ - Testing the targattrfilters keyword that allows access control based on the value of the + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that we can use MODIFY:delete to entirely remove an attribute if we have not del rights to all attr values + :id: a6862eaa-7aa9-11e8-8bf9-8c16451d917b :setup: server :steps: @@ -414,8 +425,8 @@ def test_remove_an_attribute_if_we_donot_have_del_rights_to_all_attr_value( 3. Operation should succeed """ ACI_BODY = '(targattrfilters = "add=title:(title=engineer), del=title:(|(title=architect)' \ - '(title=idiot))")(version 3.0; acl "$tet_thistest"; allow (write) ' \ - '(userdn = "ldap:///{}") ;)'.format(USER_WITH_ACI_DELADD) + '(title=idiot))")(version 3.0; acl "{}"; allow (write) ' \ + '(userdn = "ldap:///{}") ;)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) _AddTitleWithRoot(topo, "architect").add() _AddTitleWithRoot(topo, "sailor").add() @@ -426,12 +437,12 @@ def test_remove_an_attribute_if_we_donot_have_del_rights_to_all_attr_value( def test_remove_an_attribute_if_we_have_del_rights_to_all_attr_values( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): - """ - Testing the targattrfilters keyword that allows access control based on the value of the + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that we can use MODIFY:replace to entirely remove an attribute if we have del rights to all attr values + :id: ab04c7e8-7aa9-11e8-84db-8c16451d917b :setup: server :steps: @@ -444,8 +455,8 @@ def test_remove_an_attribute_if_we_have_del_rights_to_all_attr_values( 3. Operation should succeed """ ACI_BODY = '(targattrfilters = "add=title:(title=engineer), del=title:(|(title=architect)' \ - '(title=idiot))")(version 3.0; acl "$tet_thistest"; allow (write) ' \ - '(userdn = "ldap:///{}") ;)'.format(USER_WITH_ACI_DELADD) + '(title=idiot))")(version 3.0; acl "{}"; allow (write) ' \ + '(userdn = "ldap:///{}") ;)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) _AddTitleWithRoot(topo, "architect").add() _AddTitleWithRoot(topo, "idiot").add() @@ -455,12 +466,12 @@ def test_remove_an_attribute_if_we_have_del_rights_to_all_attr_values( def test_cantnot_delete_an_entry_with_attribute_values_we_are_not_allowed_delete( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): - """ - Testing the targattrfilters keyword that allows access control based on the value of + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) - Test we cannot DELETE an entry with attribute values we are not allowed delete, + Test we cannot DELETE an entry with attribute values we are not allowed delete + :id: b525d94c-7aa9-11e8-8539-8c16451d917b :setup: server :steps: @@ -474,7 +485,7 @@ def test_cantnot_delete_an_entry_with_attribute_values_we_are_not_allowed_delete """ ACI_BODY = '(targattrfilters = "add=title:(|(title=engineer)(title=cool dude)(title=scum)), ' \ 'del=title:(|(title=engineer)(title=cool dude)(title=scum))")(version 3.0; ' \ - 'aci "$tet_thistest"; allow (delete) userdn = "ldap:///{}";)'.format(USER_WITH_ACI_DELADD) + 'aci "{}"; allow (delete) userdn = "ldap:///{}";)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) _AddFREDWithRoot(topo, "engineer", "cool dude", "ANuj").create() conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) @@ -484,12 +495,12 @@ def test_cantnot_delete_an_entry_with_attribute_values_we_are_not_allowed_delete def test_we_can_add_and_delete_an_entry_with_attribute_values_we_are_allowed_add_and_delete( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): - """ - Testing the targattrfilters keyword that allows access control based on the value of the + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test we can DELETE an entry with attribute values we are allowed delete + :id: ba138e54-7aa9-11e8-8037-8c16451d917b :setup: server :steps: @@ -503,7 +514,7 @@ def test_we_can_add_and_delete_an_entry_with_attribute_values_we_are_allowed_add """ ACI_BODY = '(targattrfilters = "add=title:(|(title=engineer)(title=cool dude)(title=scum)), ' \ 'del=title:(|(title=engineer)(title=cool dude)(title=scum))")(version 3.0; ' \ - 'aci "$tet_thistest"; allow (delete) userdn = "ldap:///{}";)'.format(USER_WITH_ACI_DELADD) + 'aci "{}"; allow (delete) userdn = "ldap:///{}";)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) _AddFREDWithRoot(topo, "engineer", "cool dude", "scum").create() conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) @@ -511,12 +522,12 @@ def test_we_can_add_and_delete_an_entry_with_attribute_values_we_are_allowed_add UserAccount(conn, FRED).delete() -def test_allow_title(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the value of the +def test_allow_title(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that if attr appears in targetattr and in targattrfilters then targattrfilters applies--ie. targattrfilters is a refinement of targattrfilters. + :id: beadf328-7aa9-11e8-bb08-8c16451d917b :setup: server :steps: @@ -530,8 +541,8 @@ def test_allow_title(topo, _add_user, aci_of_user): """ ACI_BODY = '(targetattr="title")(targattrfilters = "add=title:(|(title=engineer)' \ '(title=cool dude)(title=scum)), del=title:(|(title=engineer)(title=cool dude)' \ - '(title=scum))")(version 3.0; aci "$tet_thistest"; allow (write) ' \ - 'userdn = "ldap:///{}";)'.format(USER_WITH_ACI_DELADD) + '(title=scum))")(version 3.0; aci "{}"; allow (write) ' \ + 'userdn = "ldap:///{}";)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) _AddTitleWithRoot(topo, "engineer").add() _AddTitleWithRoot(topo, "cool dude").add() @@ -541,11 +552,11 @@ def test_allow_title(topo, _add_user, aci_of_user): _ModTitleArchitectJeffVedder(topo, "topdog", conn).add() -def test_allow_to_modify(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the value of the +def test_allow_to_modify(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that I can have secretary in targetattr and title in targattrfilters. + :id: c32e4704-7aa9-11e8-951d-8c16451d917b :setup: server :steps: @@ -559,8 +570,8 @@ def test_allow_to_modify(topo, _add_user, aci_of_user): """ ACI_BODY = '(targetattr="secretary")(targattrfilters = "add=title:(|(title=engineer)' \ '(title=cool dude)(title=scum)), del=title:(|(title=engineer)(title=cool dude)' \ - '(title=scum))")(version 3.0; aci "$tet_thistest"; allow (write)' \ - ' userdn = "ldap:///{}";)'.format(USER_WITH_ACI_DELADD) + '(title=scum))")(version 3.0; aci "{}"; allow (write)' \ + ' userdn = "ldap:///{}";)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) _AddTitleWithRoot(topo, "engineer").add() _AddTitleWithRoot(topo, "cool dude").add() @@ -571,11 +582,11 @@ def test_allow_to_modify(topo, _add_user, aci_of_user): assert user.get_attr_val('secretary') -def test_selfwrite_does_not_confer_write_on_a_targattrfilters_atribute(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the value of +def test_selfwrite_does_not_confer_write_on_a_targattrfilters_atribute(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Selfwrite does not confer "write" on a targattrfilters atribute. + :id: c7b9ec2e-7aa9-11e8-ba4a-8c16451d917b :setup: server :steps: @@ -589,7 +600,7 @@ def test_selfwrite_does_not_confer_write_on_a_targattrfilters_atribute(topo, _ad """ ACI_BODY = '(targattrfilters = "add=title:(|(title=engineer)(title=cool dude)(title=scum)), ' \ 'del=title:(|(title=engineer)(title=cool dude)(title=scum))")(version 3.0; ' \ - 'aci "$tet_thistest"; allow (selfwrite) userdn = "ldap:///{}";)'.format(USER_WITH_ACI_DELADD) + 'aci "{}"; allow (selfwrite) userdn = "ldap:///{}";)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) # aci will not allow to add selfwrite_does_not_confer_write_on_a_targattrfilters_atribute conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) @@ -598,12 +609,12 @@ def test_selfwrite_does_not_confer_write_on_a_targattrfilters_atribute(topo, _ad def test_selfwrite_continues_to_give_rights_to_attr_in_targetattr_list( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): - """ - Testing the targattrfilters keyword that allows access control based on the value of + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Selfwrite continues to give rights to attr in targetattr list. + :id: cd287680-7aa9-11e8-a8e2-8c16451d917b :setup: server :steps: @@ -617,8 +628,8 @@ def test_selfwrite_continues_to_give_rights_to_attr_in_targetattr_list( """ ACI_BODY = '(targetattr="secretary")(targattrfilters = "add=title:(|(title=engineer)' \ '(title=cool dude)(title=scum)), del=title:(|(title=engineer)(title=cool dude)' \ - '(title=scum))")(version 3.0; aci "$tet_thistest"; allow (selfwrite) ' \ - 'userdn = "ldap:///{}";)'.format(USER_WITH_ACI_DELADD) + '(title=scum))")(version 3.0; aci "{}"; allow (selfwrite) ' \ + 'userdn = "ldap:///{}";)'.format(request.node.name, USER_WITH_ACI_DELADD) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) # selfwrite_continues_to_give_rights_to_attr_in_targetattr_list conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) @@ -627,12 +638,12 @@ def test_selfwrite_continues_to_give_rights_to_attr_in_targetattr_list( def test_add_an_attribute_value_we_are_allowed_to_add_with_ldapanyone( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): - """ - Testing the targattrfilters keyword that allows access control based on the value of the + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that we can MODIFY:add an attribute value we are allowed to add with ldap:///anyone + :id: d1e1d7ac-7aa9-11e8-b968-8c16451d917b :setup: server :steps: @@ -645,7 +656,7 @@ def test_add_an_attribute_value_we_are_allowed_to_add_with_ldapanyone( 3. Operation should succeed """ ACI_BODY = '(targattrfilters = "add=title:(title=architect), del=title:(title=architect)")' \ - '(version 3.0; acl "$tet_thistest"; allow (write) userdn = "ldap:///anyone";)' + '(version 3.0; acl "{}"; allow (write) userdn = "ldap:///anyone";)'.format(request.node.name) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) _AddTitleWithRoot(topo, "engineer").add() # aci will allow to add title architect @@ -653,12 +664,12 @@ def test_add_an_attribute_value_we_are_allowed_to_add_with_ldapanyone( _ModTitleArchitectJeffVedder(topo, "architect", conn).add() -def test_hierarchy(topo, _add_user, aci_of_user): - """ - Testing the targattrfilters keyword that allows access control based on the value of +def test_hierarchy(topo, _add_user, aci_of_user, request): + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that with two targattrfilters in the hierarchy that the general one applies. - This is the correct behaviour, even if it's a bit + This is the correct behaviour, even if it's a bit confusing + :id: d7ae354a-7aa9-11e8-8b0d-8c16451d917b :setup: server :steps: @@ -670,10 +681,10 @@ def test_hierarchy(topo, _add_user, aci_of_user): 2. Operation should succeed 3. Operation should succeed """ - ACI_BODY = '(targattrfilters = "add=title:(title=arch*)")(version 3.0; acl "$tet_thistest"; ' \ - 'allow (write) (userdn = "ldap:///anyone") ;)' + ACI_BODY = '(targattrfilters = "add=title:(title=arch*)")(version 3.0; acl "{}"; ' \ + 'allow (write) (userdn = "ldap:///anyone") ;)'.format(request.node.name) ACI_BODY1 = '(targattrfilters = "add=title:(title=architect)")(version 3.0; ' \ - 'acl "$tet_thistest"; allow (write) (userdn = "ldap:///anyone") ;)' + 'acl "{}"; allow (write) (userdn = "ldap:///anyone") ;)'.format(request.node.name) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY1) _AddTitleWithRoot(topo, "engineer").add() @@ -686,12 +697,12 @@ def test_hierarchy(topo, _add_user, aci_of_user): def test_targattrfilters_and_search_permissions_and_that_ldapmodify_works_as_expected( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): - """ - Testing the targattrfilters keyword that allows access control based on the value of the + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that we can have targattrfilters and search permissions and that ldapmodify works as expected. + :id: ddae7a22-7aa9-11e8-ad6b-8c16451d917b :setup: server :steps: @@ -704,8 +715,8 @@ def test_targattrfilters_and_search_permissions_and_that_ldapmodify_works_as_exp 3. Operation should succeed """ ACI_BODY = '(targetattr="secretary || objectclass || mail")(targattrfilters = "add=title:' \ - '(title=arch*)")(version 3.0; acl "$tet_thistest"; ' \ - 'allow (write,read,search,compare) (userdn = "ldap:///anyone") ;)' + '(title=arch*)")(version 3.0; acl "{}"; ' \ + 'allow (write,read,search,compare) (userdn = "ldap:///anyone") ;)'.format(request.node.name) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) # aci will allow to add title architect conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) @@ -713,12 +724,12 @@ def test_targattrfilters_and_search_permissions_and_that_ldapmodify_works_as_exp def test_targattrfilters_and_search_permissions_and_that_ldapmodify_works_as_expected_two( - topo, _add_user, aci_of_user + topo, _add_user, aci_of_user, request ): - """ - Testing the targattrfilters keyword that allows access control based on the value of + """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) Test that we can have targattrfilters and search permissions and that ldapsearch works as expected. + :id: e25d116e-7aa9-11e8-81d8-8c16451d917b :setup: server :steps: @@ -731,8 +742,8 @@ def test_targattrfilters_and_search_permissions_and_that_ldapmodify_works_as_exp 3. Operation should succeed """ ACI_BODY = '(targetattr="secretary || objectclass || mail")(targattrfilters = ' \ - '"add=title:(title=arch*)")(version 3.0; acl "$tet_thistest"; allow ' \ - '(write,read,search,compare) (userdn = "ldap:///anyone") ;)' + '"add=title:(title=arch*)")(version 3.0; acl "{}"; allow ' \ + '(write,read,search,compare) (userdn = "ldap:///anyone") ;)'.format(request.node.name) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) conn = Anonymous(topo.standalone).bind() user = UserAccount(conn, USER_DELADD) diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py index 02b73ee85..97908c31c 100644 --- a/dirsrvtests/tests/suites/basic/basic_test.py +++ b/dirsrvtests/tests/suites/basic/basic_test.py @@ -7,10 +7,6 @@ # --- END COPYRIGHT BLOCK --- # -""" - :Requirement: Basic Directory Server Operations -""" - from subprocess import check_output, PIPE, run from lib389 import DirSrv from lib389.idm.user import UserAccounts @@ -255,11 +251,11 @@ def test_basic_import_export(topology_st, import_example_ldif): """ log.info('Running test_basic_import_export...') - # # Test online/offline LDIF imports # topology_st.standalone.start() + # topology_st.standalone.config.set('nsslapd-errorlog-level', '1') # Generate a test ldif (50k entries) log.info("Generating LDIF...") @@ -267,6 +263,7 @@ def test_basic_import_export(topology_st, import_example_ldif): import_ldif = ldif_dir + '/basic_import.ldif' dbgen_users(topology_st.standalone, 50000, import_ldif, DEFAULT_SUFFIX) + # Online log.info("Importing LDIF online...") import_task = ImportTask(topology_st.standalone) @@ -937,7 +934,7 @@ def test_mod_def_rootdse_attr(topology_st, import_example_ldif, rootdse_attr): :id: c7831e04-f458-4e23-83c7-b6f66109f639 :parametrized: yes :setup: Standalone instance and we are using rootdse_attr fixture which -adds nsslapd-return-default-opattr attr with value of one operation attribute. + adds nsslapd-return-default-opattr attr with value of one operation attribute. :steps: 1. Make an ldapsearch for rootdse attribute @@ -1003,7 +1000,7 @@ def test_basic_anonymous_search(topology_st, create_users): @pytest.mark.bz915801 def test_search_original_type(topology_st, create_users): """Test ldapsearch returning original attributes - using nsslapd-search-return-original-type-switch + using nsslapd-search-return-original-type-switch :id: d7831d04-f558-4e50-93c7-b6f77109f640 :setup: Standalone instance @@ -1095,7 +1092,7 @@ def test_critical_msg_on_empty_range_idl(topology_st): :setup: Standalone instance :steps: 1. Create an index for internationalISDNNumber. (attribute chosen because it is - unlikely that previous tests used it) + unlikely that previous tests used it) 2. telephoneNumber being indexed by default create 20 users without telephoneNumber 3. add a telephoneNumber value and delete it to trigger an empty index database 4. Do a search that triggers a range lookup on empty telephoneNumber @@ -1105,7 +1102,7 @@ def test_critical_msg_on_empty_range_idl(topology_st): 2. This should pass 3. This should pass 4. This should pass on normal build but could abort a debug build - 4. This should pass + 5. This should pass """ indexedAttr = 'internationalISDNNumber' @@ -1206,7 +1203,7 @@ def test_ldbm_modification_audit_log(topology_st): assert conn.searchAuditLog('%s: %s' % (attr, VALUE)) -@pytest.mark.skipif(not get_user_is_root() or not default_paths.perl_enabled or ds_is_older('1.4.0.0'), +@pytest.mark.skipif(not get_user_is_root() or ds_is_older('1.4.0.0'), reason="This test is only required if perl is enabled, and requires root.") def test_dscreate(request): """Test that dscreate works, we need this for now until setup-ds.pl is @@ -1356,7 +1353,7 @@ sample_entries = yes return inst -@pytest.mark.skipif(not get_user_is_root() or not default_paths.perl_enabled or ds_is_older('1.4.2.0'), +@pytest.mark.skipif(not get_user_is_root() or ds_is_older('1.4.2.0'), reason="This test is only required with new admin cli, and requires root.") @pytest.mark.bz1748016 @pytest.mark.ds50581 @@ -1367,7 +1364,7 @@ def test_dscreate_ldapi(dscreate_long_instance): :id: 5d72d955-aff8-4741-8c9a-32c1c707cf1f :setup: None :steps: - 1. create an instance with a long serverId name, that open a ldapi connection + 1. Ccreate an instance with a long serverId name, that open a ldapi connection 2. Connect with ldapi, that hit 50581 and crash the instance :expectedresults: 1. Should succeeds @@ -1378,7 +1375,7 @@ def test_dscreate_ldapi(dscreate_long_instance): log.info(root_dse.get_supported_ctrls()) -@pytest.mark.skipif(not get_user_is_root() or not default_paths.perl_enabled or ds_is_older('1.4.2.0'), +@pytest.mark.skipif(not get_user_is_root() or ds_is_older('1.4.2.0'), reason="This test is only required with new admin cli, and requires root.") @pytest.mark.bz1715406 @pytest.mark.ds50923 diff --git a/dirsrvtests/tests/suites/ds_logs/ds_logs_test.py b/dirsrvtests/tests/suites/ds_logs/ds_logs_test.py index 94686f5f2..d67bcb13e 100644 --- a/dirsrvtests/tests/suites/ds_logs/ds_logs_test.py +++ b/dirsrvtests/tests/suites/ds_logs/ds_logs_test.py @@ -1,25 +1,26 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2015 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). # See LICENSE for details. # --- END COPYRIGHT BLOCK --- # +from decimal import * import os import logging import pytest -import subprocess from lib389._mapped_object import DSLdapObject from lib389.topologies import topology_st from lib389.plugins import AutoMembershipPlugin, ReferentialIntegrityPlugin, AutoMembershipDefinitions from lib389.idm.user import UserAccounts from lib389.idm.group import Groups from lib389.idm.organizationalunit import OrganizationalUnits -from lib389._constants import DEFAULT_SUFFIX, LOG_ACCESS_LEVEL, DN_CONFIG, HOST_STANDALONE, PORT_STANDALONE, DN_DM, PASSWORD -from lib389.utils import ds_is_older +from lib389._constants import DEFAULT_SUFFIX, LOG_ACCESS_LEVEL +from lib389.utils import ds_is_older, ds_is_newer import ldap import glob +import re pytestmark = pytest.mark.tier1 @@ -30,7 +31,6 @@ PLUGIN_TIMESTAMP = 'nsslapd-logging-hr-timestamps-enabled' PLUGIN_LOGGING = 'nsslapd-plugin-logging' USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX - def add_users(topology_st, users_num): users = UserAccounts(topology_st, DEFAULT_SUFFIX) log.info('Adding %d users' % users_num) @@ -161,6 +161,20 @@ def clean_access_logs(topology_st, request): return clean_access_logs +@pytest.fixture(scope="function") +def remove_users(topology_st, request): + def _remove_users(): + topo = topology_st.standalone + users = UserAccounts(topo, DEFAULT_SUFFIX) + entries = users.list() + assert len(entries) > 0 + + log.info("Removing all added users") + for entry in entries: + delete_obj(entry) + + request.addfinalizer(_remove_users) + def set_audit_log_config_values(topology_st, request, enabled, logsize): topo = topology_st.standalone @@ -181,6 +195,17 @@ def set_audit_log_config_values(topology_st, request, enabled, logsize): def set_audit_log_config_values_to_rotate(topology_st, request): set_audit_log_config_values(topology_st, request, 'on', '1') +@pytest.fixture(scope="function") +def disable_access_log_buffering(topology_st, request): + log.info('Disable access log buffering') + topology_st.standalone.config.set('nsslapd-accesslog-logbuffering', 'off') + def fin(): + log.info('Enable access log buffering') + topology_st.standalone.config.set('nsslapd-accesslog-logbuffering', 'on') + + request.addfinalizer(fin) + + return disable_access_log_buffering @pytest.mark.bz1273549 def test_check_default(topology_st): @@ -226,11 +251,11 @@ def test_plugin_set_invalid(topology_st): log.info('test_plugin_set_invalid - Expect to fail with junk value') with pytest.raises(ldap.OPERATIONS_ERROR): - result = topology_st.standalone.config.set(PLUGIN_TIMESTAMP, 'JUNK') + topology_st.standalone.config.set(PLUGIN_TIMESTAMP, 'JUNK') @pytest.mark.bz1273549 -def test_log_plugin_on(topology_st): +def test_log_plugin_on(topology_st, remove_users): """Check access logs for millisecond, when nsslapd-logging-hr-timestamps-enabled=ON @@ -266,7 +291,7 @@ def test_log_plugin_on(topology_st): @pytest.mark.bz1273549 -def test_log_plugin_off(topology_st): +def test_log_plugin_off(topology_st, remove_users): """Milliseconds should be absent from access logs when nsslapd-logging-hr-timestamps-enabled=OFF @@ -303,6 +328,7 @@ def test_log_plugin_off(topology_st): topology_st.standalone.deleteAccessLogs() # Now generate some fresh logs + add_users(topology_st.standalone, 10) search_users(topology_st.standalone) log.info('Restart the server to flush the logs') @@ -317,8 +343,9 @@ def test_log_plugin_off(topology_st): @pytest.mark.xfail(ds_is_older('1.4.0'), reason="May fail on 1.3.x because of bug 1358706") @pytest.mark.bz1358706 @pytest.mark.ds49029 -def test_internal_log_server_level_0(topology_st, clean_access_logs): +def test_internal_log_server_level_0(topology_st, clean_access_logs, disable_access_log_buffering): """Tests server-initiated internal operations + :id: 798d06fe-92e8-4648-af66-21349c20638e :setup: Standalone instance :steps: @@ -362,22 +389,23 @@ def test_internal_log_server_level_0(topology_st, clean_access_logs): @pytest.mark.xfail(ds_is_older('1.4.0'), reason="May fail on 1.3.x because of bug 1358706") @pytest.mark.bz1358706 @pytest.mark.ds49029 -def test_internal_log_server_level_4(topology_st, clean_access_logs): +def test_internal_log_server_level_4(topology_st, clean_access_logs, disable_access_log_buffering): """Tests server-initiated internal operations + :id: a3500e47-d941-4575-b399-e3f4b49bc4b6 :setup: Standalone instance :steps: 1. Set nsslapd-plugin-logging to on 2. Configure access log level to only 4 3. Check the access logs, it should contain info about MOD operation of cn=config and other - internal operations should have the conn field set to Internal - and all values inside parenthesis set to 0. + internal operations should have the conn field set to Internal + and all values inside parenthesis set to 0. :expectedresults: 1. Operation should be successful 2. Operation should be successful 3. Access log should contain correct internal log formats with cn=config modification: - "(Internal) op=2(1)(1)" - "conn=Internal(0)" + "(Internal) op=2(1)(1)" + "conn=Internal(0)" """ topo = topology_st.standalone @@ -398,8 +426,8 @@ def test_internal_log_server_level_4(topology_st, clean_access_logs): log.info("Check if access log contains internal MOD operation in correct format") # (Internal) op=2(2)(1) SRCH base="cn=config assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) SRCH base="cn=config.*') - # (Internal) op=2(2)(1) RESULT err=0 tag=48 nentries=1 - assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) RESULT err=0 tag=48 nentries=1.*') + # (Internal) op=2(2)(1) RESULT err=0 tag=48 nentries= + assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) RESULT err=0 tag=48 nentries=.*') log.info("Check if the other internal operations have the correct format") # conn=Internal(0) op=0 @@ -411,8 +439,9 @@ def test_internal_log_server_level_4(topology_st, clean_access_logs): @pytest.mark.xfail(ds_is_older('1.4.0'), reason="May fail on 1.3.x because of bug 1358706") @pytest.mark.bz1358706 @pytest.mark.ds49029 -def test_internal_log_level_260(topology_st, add_user_log_level_260): +def test_internal_log_level_260(topology_st, add_user_log_level_260, disable_access_log_buffering): """Tests client initiated operations when automember plugin is enabled + :id: e68a303e-c037-42b2-a5a0-fbea27c338a9 :setup: Standalone instance with internal operation logging on and nsslapd-plugin-logging to on @@ -465,9 +494,10 @@ def test_internal_log_level_260(topology_st, add_user_log_level_260): # 'newrdn="uid=new_test_user_777" newsuperior="dc=example,dc=com" assert topo.ds_access_log.match(r'.*op=[0-9]+ MODRDN dn="uid=test_user_777,ou=branch1,dc=example,dc=com" ' 'newrdn="uid=new_test_user_777" newsuperior="dc=example,dc=com".*') - # (Internal) op=12(1)(1) SRCH base="uid=test_user_777, ou=branch1,dc=example,dc=com" - assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) SRCH base="uid=test_user_777,' - 'ou=branch1,dc=example,dc=com".*') + if ds_is_older(('1.4.3.9', '1.4.4.3')): + # (Internal) op=12(1)(1) SRCH base="uid=test_user_777, ou=branch1,dc=example,dc=com" + assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) SRCH base="uid=test_user_777,' + 'ou=branch1,dc=example,dc=com".*') # (Internal) op=12(1)(1) RESULT err=0 tag=48 nentries=1 assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) RESULT err=0 tag=48 nentries=1.*') # op=12 RESULT err=0 tag=109 @@ -476,9 +506,10 @@ def test_internal_log_level_260(topology_st, add_user_log_level_260): log.info("Check the access logs for DEL operation of the user") # op=15 DEL dn="uid=new_test_user_777,dc=example,dc=com" assert topo.ds_access_log.match(r'.*op=[0-9]+ DEL dn="uid=new_test_user_777,dc=example,dc=com".*') - # (Internal) op=15(1)(1) SRCH base="uid=new_test_user_777, dc=example,dc=com" - assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) SRCH base="uid=new_test_user_777,' - 'dc=example,dc=com".*') + if ds_is_older(('1.4.3.9', '1.4.4.3')): + # (Internal) op=15(1)(1) SRCH base="uid=new_test_user_777, dc=example,dc=com" + assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) SRCH base="uid=new_test_user_777,' + 'dc=example,dc=com".*') # (Internal) op=15(1)(1) RESULT err=0 tag=48 nentries=1 assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) RESULT err=0 tag=48 nentries=1.*') # op=15 RESULT err=0 tag=107 @@ -492,8 +523,9 @@ def test_internal_log_level_260(topology_st, add_user_log_level_260): @pytest.mark.xfail(ds_is_older('1.4.0'), reason="May fail on 1.3.x because of bug 1358706") @pytest.mark.bz1358706 @pytest.mark.ds49029 -def test_internal_log_level_131076(topology_st, add_user_log_level_131076): +def test_internal_log_level_131076(topology_st, add_user_log_level_131076, disable_access_log_buffering): """Tests client-initiated operations while referential integrity plugin is enabled + :id: 44836ac9-dabd-4a8c-abd5-ecd7c2509739 :setup: Standalone instance Configure access log level to - 131072 + 4 @@ -547,9 +579,10 @@ def test_internal_log_level_131076(topology_st, add_user_log_level_131076): # 'newrdn="uid=new_test_user_777" newsuperior="dc=example,dc=com" assert not topo.ds_access_log.match(r'.*op=[0-9]+ MODRDN dn="uid=test_user_777,ou=branch1,dc=example,dc=com" ' 'newrdn="uid=new_test_user_777" newsuperior="dc=example,dc=com".*') - # (Internal) op=12(1)(1) SRCH base="uid=test_user_777, ou=branch1,dc=example,dc=com" - assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) SRCH base="uid=test_user_777,' - 'ou=branch1,dc=example,dc=com".*') + if ds_is_older(('1.4.3.9', '1.4.4.3')): + # (Internal) op=12(1)(1) SRCH base="uid=test_user_777, ou=branch1,dc=example,dc=com" + assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) SRCH base="uid=test_user_777,' + 'ou=branch1,dc=example,dc=com".*') # (Internal) op=12(1)(1) RESULT err=0 tag=48 nentries=1 assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) RESULT err=0 tag=48 nentries=1.*') # op=12 RESULT err=0 tag=109 @@ -558,9 +591,10 @@ def test_internal_log_level_131076(topology_st, add_user_log_level_131076): log.info("Check the access logs for DEL operation of the user") # op=15 DEL dn="uid=new_test_user_777,dc=example,dc=com" assert not topo.ds_access_log.match(r'.*op=[0-9]+ DEL dn="uid=new_test_user_777,dc=example,dc=com".*') - # (Internal) op=15(1)(1) SRCH base="uid=new_test_user_777, dc=example,dc=com" - assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) SRCH base="uid=new_test_user_777,' - 'dc=example,dc=com".*') + if ds_is_older(('1.4.3.9', '1.4.4.3')): + # (Internal) op=15(1)(1) SRCH base="uid=new_test_user_777, dc=example,dc=com" + assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) SRCH base="uid=new_test_user_777,' + 'dc=example,dc=com".*') # (Internal) op=15(1)(1) RESULT err=0 tag=48 nentries=1 assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) RESULT err=0 tag=48 nentries=1.*') # op=15 RESULT err=0 tag=107 @@ -574,8 +608,9 @@ def test_internal_log_level_131076(topology_st, add_user_log_level_131076): @pytest.mark.xfail(ds_is_older('1.4.0'), reason="May fail on 1.3.x because of bug 1358706") @pytest.mark.bz1358706 @pytest.mark.ds49029 -def test_internal_log_level_516(topology_st, add_user_log_level_516): +def test_internal_log_level_516(topology_st, add_user_log_level_516, disable_access_log_buffering): """Tests client initiated operations when referential integrity plugin is enabled + :id: bee1d681-763d-4fa5-aca2-569cf93f8b71 :setup: Standalone instance Configure access log level to - 512+4 @@ -624,34 +659,34 @@ def test_internal_log_level_516(topology_st, add_user_log_level_516): assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) RESULT err=0 tag=48 nentries=1*') # (Internal) op=10(1)(1) RESULT err=0 tag=48 assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) RESULT err=0 tag=48.*') - # op=10 RESULT err=0 tag=105 - assert not topo.ds_access_log.match(r'.*op=[0-9]+ RESULT err=0 tag=105.*') log.info("Check the access logs for MOD operation of the user") # op=12 MODRDN dn="uid=test_user_777,ou=branch1,dc=example,dc=com" ' # 'newrdn="uid=new_test_user_777" newsuperior="dc=example,dc=com" assert not topo.ds_access_log.match(r'.*op=[0-9]+ MODRDN dn="uid=test_user_777,ou=branch1,dc=example,dc=com" ' 'newrdn="uid=new_test_user_777" newsuperior="dc=example,dc=com".*') - # Internal) op=12(1)(1) SRCH base="uid=test_user_777, ou=branch1,dc=example,dc=com" - assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) SRCH base="uid=test_user_777,' - 'ou=branch1,dc=example,dc=com".*') - # (Internal) op=12(1)(1) ENTRY dn="uid=test_user_777, ou=branch1,dc=example,dc=com" - assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) ENTRY dn="uid=test_user_777,' - 'ou=branch1,dc=example,dc=com".*') + if ds_is_older(('1.4.3.9', '1.4.4.3')): + # Internal) op=12(1)(1) SRCH base="uid=test_user_777, ou=branch1,dc=example,dc=com" + assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) SRCH base="uid=test_user_777,' + 'ou=branch1,dc=example,dc=com".*') + # (Internal) op=12(1)(1) ENTRY dn="uid=test_user_777, ou=branch1,dc=example,dc=com" + assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) ENTRY dn="uid=test_user_777,' + 'ou=branch1,dc=example,dc=com".*') # (Internal) op=12(1)(1) RESULT err=0 tag=48 nentries=1 assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) RESULT err=0 tag=48 nentries=1.*') - # op=12 RESULT err=0 tag=109 - assert not topo.ds_access_log.match(r'.*op=[0-9]+ RESULT err=0 tag=109.*') + # op=12 RESULT err=0 tag=48 + assert not topo.ds_access_log.match(r'.*op=[0-9]+ RESULT err=0 tag=48.*') log.info("Check the access logs for DEL operation of the user") # op=15 DEL dn="uid=new_test_user_777,dc=example,dc=com" assert not topo.ds_access_log.match(r'.*op=[0-9]+ DEL dn="uid=new_test_user_777,dc=example,dc=com".*') - # (Internal) op=15(1)(1) SRCH base="uid=new_test_user_777, dc=example,dc=com" - assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) SRCH base="uid=new_test_user_777,' - 'dc=example,dc=com".*') - # (Internal) op=15(1)(1) ENTRY dn="uid=new_test_user_777, dc=example,dc=com" - assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) ENTRY dn="uid=new_test_user_777,' - 'dc=example,dc=com".*') + if ds_is_older(('1.4.3.9', '1.4.4.3')): + # (Internal) op=15(1)(1) SRCH base="uid=new_test_user_777, dc=example,dc=com" + assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) SRCH base="uid=new_test_user_777,' + 'dc=example,dc=com".*') + # (Internal) op=15(1)(1) ENTRY dn="uid=new_test_user_777, dc=example,dc=com" + assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) ENTRY dn="uid=new_test_user_777,' + 'dc=example,dc=com".*') # (Internal) op=15(1)(1) RESULT err=0 tag=48 nentries=1 assert topo.ds_access_log.match(r'.*\(Internal\) op=[0-9]+\([0-9]+\)\([0-9]+\) RESULT err=0 tag=48 nentries=1.*') # op=15 RESULT err=0 tag=107 @@ -698,14 +733,13 @@ def test_access_log_truncated_search_message(topology_st, clean_access_logs): assert not topo.ds_access_log.match(r'.*cn500.*') - +@pytest.mark.skipif(ds_is_newer("1.4.3"), reason="rsearch was removed") @pytest.mark.xfail(ds_is_older('1.4.2.0'), reason="May fail because of bug 1732053") @pytest.mark.bz1732053 @pytest.mark.ds50510 def test_etime_at_border_of_second(topology_st, clean_access_logs): topo = topology_st.standalone - prog = os.path.join(topo.ds_paths.bin_dir, 'rsearch') cmd = [prog] @@ -741,11 +775,167 @@ def test_etime_at_border_of_second(topology_st, clean_access_logs): assert not invalid_etime +@pytest.mark.skipif(ds_is_older('1.3.10.1', '1.4.1'), reason="Fail because of bug 1749236") +@pytest.mark.bz1749236 +def test_etime_order_of_magnitude(topology_st, clean_access_logs, remove_users, disable_access_log_buffering): + """Test that the etime reported in the access log has a correct order of magnitude + + :id: e815cfa0-8136-4932-b50f-c3dfac34b0e6 + :setup: Standalone instance + :steps: + 1. Unset log buffering for the access log + 2. Delete potential existing access logs + 3. Add users + 4. Search users + 5. Restart the server to flush the logs + 6. Parse the access log looking for the SRCH operation log + 7. From the SRCH string get the start time and op number of the operation + 8. From the op num find the associated RESULT string in the access log + 9. From the RESULT string get the end time and the etime for the operation + 10. Calculate the ratio between the calculated elapsed time (end time - start time) and the logged etime + :expectedresults: + 1. access log buffering is off + 2. Previously existing access logs are deleted + 3. Users are successfully added + 4. Search operation is successful + 5. Server is restarted and logs are flushed + 6. SRCH operation log string is catched + 7. start time and op number are collected + 8. RESULT string is catched from the access log + 9. end time and etime are collected + 10. ratio between calculated elapsed time and logged etime is less or equal to 1 + """ + + DSLdapObject(topology_st.standalone, DEFAULT_SUFFIX) + + log.info('add_users') + add_users(topology_st.standalone, 30) + + log.info ('search users') + search_users(topology_st.standalone) + + log.info('parse the access logs to get the SRCH string') + # Here we are looking at the whole string logged for the search request with base ou=People,dc=example,dc=com + search_str = str(topology_st.standalone.ds_access_log.match(r'.*SRCH base="ou=People,dc=example,dc=com.*'))[1:-1] + assert len(search_str) > 0 + + # the search_str returned looks like : + # [23/Apr/2020:06:06:14.360857624 -0400] conn=1 op=93 SRCH base="ou=People,dc=example,dc=com" scope=2 filter="(&(objectClass=account)(objectClass=posixaccount)(objectClass=inetOrgPerson)(objectClass=organizationalPerson))" attrs="distinguishedName" + + log.info('get the operation start time from the SRCH string') + # Here we are getting the sec.nanosec part of the date, '14.360857624' in the example above + start_time = (search_str.split()[0]).split(':')[3] + + log.info('get the OP number from the SRCH string') + # Here we are getting the op number, 'op=93' in the above example + op_num = search_str.split()[3] + + log.info('get the RESULT string matching the SRCH OP number') + # Here we are looking at the RESULT string for the above search op, 'op=93' in this example + result_str = str(topology_st.standalone.ds_access_log.match(r'.*{} RESULT*'.format(op_num)))[1:-1] + assert len(result_str) > 0 + + # The result_str returned looks like : + # For ds older than 1.4.3.8: [23/Apr/2020:06:06:14.366429900 -0400] conn=1 op=93 RESULT err=0 tag=101 nentries=30 etime=0.005723017 + # For ds newer than 1.4.3.8: [21/Oct/2020:09:27:50.095209871 -0400] conn=1 op=96 RESULT err=0 tag=101 nentries=30 wtime=0.000412584 optime=0.005428971 etime=0.005836077 + + log.info('get the operation end time from the RESULT string') + # Here we are getting the sec.nanosec part of the date, '14.366429900' in the above example + end_time = (result_str.split()[0]).split(':')[3] + + log.info('get the logged etime for the operation from the RESULT string') + # Here we are getting the etime value, '0.005723017' in the example above + if ds_is_older('1.4.3.8'): + etime = result_str.split()[8].split('=')[1][:-3] + else: + etime = result_str.split()[10].split('=')[1][:-3] + + log.info('Calculate the ratio between logged etime for the operation and elapsed time from its start time to its end time - should be around 1') + etime_ratio = (Decimal(end_time) - Decimal(start_time)) // Decimal(etime) + assert etime_ratio <= 1 + + +@pytest.mark.skipif(ds_is_older('1.4.3.8'), reason="Fail because of bug 1850275") +@pytest.mark.bz1850275 +def test_optime_and_wtime_keywords(topology_st, clean_access_logs, remove_users, disable_access_log_buffering): + """Test that the new optime and wtime keywords are present in the access log and have correct values + + :id: dfb4a49d-1cfc-400e-ba43-c107f58d62cf + :setup: Standalone instance + :steps: + 1. Unset log buffering for the access log + 2. Delete potential existing access logs + 3. Add users + 4. Search users + 5. Parse the access log looking for the SRCH operation log + 6. From the SRCH string get the op number of the operation + 7. From the op num find the associated RESULT string in the access log + 8. Search for the wtime optime keywords in the RESULT string + 9. From the RESULT string get the wtime, optime and etime values for the operation + 10. Check that optime + wtime is approximatively etime + :expectedresults: + 1. access log buffering is off + 2. Previously existing access logs are deleted + 3. Users are successfully added + 4. Search operation is successful + 5. SRCH operation log string is catched + 6. op number is collected + 7. RESULT string is catched from the access log + 8. wtime and optime keywords are collected + 9. wtime, optime and etime values are collected + 10. (optime + wtime) =~ etime + """ + + log.info('add_users') + add_users(topology_st.standalone, 30) + + log.info ('search users') + search_users(topology_st.standalone) + + log.info('parse the access logs to get the SRCH string') + # Here we are looking at the whole string logged for the search request with base ou=People,dc=example,dc=com + search_str = str(topology_st.standalone.ds_access_log.match(r'.*SRCH base="ou=People,dc=example,dc=com.*'))[1:-1] + assert len(search_str) > 0 + + # the search_str returned looks like : + # [22/Oct/2020:09:47:11.951316798 -0400] conn=1 op=96 SRCH base="ou=People,dc=example,dc=com" scope=2 filter="(&(objectClass=account)(objectClass=posixaccount)(objectClass=inetOrgPerson)(objectClass=organizationalPerson))" attrs="distinguishedName" + + log.info('get the OP number from the SRCH string') + # Here we are getting the op number, 'op=96' in the above example + op_num = search_str.split()[3] + + log.info('get the RESULT string matching the SRCH op number') + # Here we are looking at the RESULT string for the above search op, 'op=96' in this example + result_str = str(topology_st.standalone.ds_access_log.match(r'.*{} RESULT*'.format(op_num)))[1:-1] + assert len(result_str) > 0 + + # The result_str returned looks like : + # [22/Oct/2020:09:47:11.963276018 -0400] conn=1 op=96 RESULT err=0 tag=101 nentries=30 wtime=0.000180294 optime=0.011966632 etime=0.012141311 + log.info('Search for the wtime keyword in the RESULT string') + assert re.search('wtime', result_str) + + log.info('get the wtime value from the RESULT string') + wtime_value = result_str.split()[8].split('=')[1][:-3] + + log.info('Search for the optime keyword in the RESULT string') + assert re.search('optime', result_str) + + log.info('get the optime value from the RESULT string') + optime_value = result_str.split()[9].split('=')[1][:-3] + + log.info('get the etime value from the RESULT string') + etime_value = result_str.split()[10].split('=')[1][:-3] + + log.info('Check that (wtime + optime) is approximately equal to etime i.e. their ratio is 1') + etime_ratio = (Decimal(wtime_value) + Decimal(optime_value)) // Decimal(etime_value) + assert etime_ratio == 1 + + @pytest.mark.xfail(ds_is_older('1.3.10.1'), reason="May fail because of bug 1662461") @pytest.mark.bz1662461 @pytest.mark.ds50428 @pytest.mark.ds49969 -def test_log_base_dn_when_invalid_attr_request(topology_st): +def test_log_base_dn_when_invalid_attr_request(topology_st, disable_access_log_buffering): """Test that DS correctly logs the base dn when a search with invalid attribute request is performed :id: 859de962-c261-4ffb-8705-97bceab1ba2c @@ -753,7 +943,7 @@ def test_log_base_dn_when_invalid_attr_request(topology_st): :steps: 1. Disable the accesslog-logbuffering config parameter 2. Delete the previous access log - 3. Perform a base search on the DEFAULT_SUFFIX, using invalid "" "" attribute request + 3. Perform a base search on the DEFAULT_SUFFIX, using ten empty attribute requests 4. Check the access log file for 'invalid attribute request' 5. Check the access log file for 'SRCH base="\(null\)"' 6. Check the access log file for 'SRCH base="DEFAULT_SUFFIX"' @@ -768,17 +958,14 @@ def test_log_base_dn_when_invalid_attr_request(topology_st): entry = DSLdapObject(topology_st.standalone, DEFAULT_SUFFIX) - log.info('Set accesslog logbuffering to off to get the log in real time') - topology_st.standalone.config.set('nsslapd-accesslog-logbuffering', 'off') - log.info('delete the previous access logs to get a fresh new one') topology_st.standalone.deleteAccessLogs() log.info("Search the default suffix, with invalid '\"\" \"\"' attribute request") - log.info("A Protocol error exception should be raised, see https://pagure.io/389-ds-base/issue/49969") - # A ldap.PROTOCOL_ERROR exception is expected + log.info("A Protocol error exception should be raised, see https://github.com/389ds/389-ds-base/issues/3028") + # A ldap.PROTOCOL_ERROR exception is expected after 10 empty values with pytest.raises(ldap.PROTOCOL_ERROR): - assert entry.get_attrs_vals_utf8(['', '']) + assert entry.get_attrs_vals_utf8(['', '', '', '', '', '', '', '', '', '', '']) # Search for appropriate messages in the access log log.info('Check the access logs for correct messages') diff --git a/dirsrvtests/tests/suites/filter/rfc3673_all_oper_attrs_test.py b/dirsrvtests/tests/suites/filter/rfc3673_all_oper_attrs_test.py index db2be9f67..c882bea5f 100644 --- a/dirsrvtests/tests/suites/filter/rfc3673_all_oper_attrs_test.py +++ b/dirsrvtests/tests/suites/filter/rfc3673_all_oper_attrs_test.py @@ -11,6 +11,7 @@ from lib389.tasks import * from lib389.utils import * from lib389.topologies import topology_st from lib389.idm.user import UserAccounts +from lib389.idm.domain import Domain from lib389._constants import DN_DM, DEFAULT_SUFFIX, DN_CONFIG, PASSWORD @@ -26,15 +27,15 @@ TEST_USER_PWD = 'all_attrs_test' TEST_PARAMS = [(DN_ROOT, False, [ 'aci', 'createTimestamp', 'creatorsName', 'modifiersName', 'modifyTimestamp', 'namingContexts', - 'nsBackendSuffix', 'nsUniqueId', 'subschemaSubentry', + 'nsBackendSuffix', 'subschemaSubentry', 'supportedControl', 'supportedExtension', 'supportedFeatures', 'supportedLDAPVersion', 'supportedSASLMechanisms', 'vendorName', 'vendorVersion' -]), + ]), (DN_ROOT, True, [ 'createTimestamp', 'creatorsName', 'modifiersName', 'modifyTimestamp', 'namingContexts', - 'nsBackendSuffix', 'nsUniqueId', 'subschemaSubentry', + 'nsBackendSuffix', 'subschemaSubentry', 'supportedControl', 'supportedExtension', 'supportedFeatures', 'supportedLDAPVersion', 'supportedSASLMechanisms', 'vendorName', 'vendorVersion' @@ -80,6 +81,18 @@ def create_user(topology_st): 'homeDirectory': '/home/test' }) + # Add anonymous access aci + ACI_TARGET = "(targetattr != \"userpassword || aci\")(target = \"ldap:///%s\")" % (DEFAULT_SUFFIX) + ACI_ALLOW = "(version 3.0; acl \"Anonymous Read access\"; allow (read,search,compare)" + ACI_SUBJECT = "(userdn=\"ldap:///anyone\");)" + ANON_ACI = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT + suffix = Domain(topology_st.standalone, DEFAULT_SUFFIX) + try: + suffix.add('aci', ANON_ACI) + except ldap.TYPE_OR_VALUE_EXISTS: + pass + + @pytest.fixture(scope="module") def user_aci(topology_st): """Don't allow modifiersName attribute for the test user @@ -156,7 +169,9 @@ def test_search_basic(topology_st, create_user, user_aci, add_attr, entries = topology_st.standalone.search_s(search_suffix, ldap.SCOPE_BASE, '(objectclass=*)', search_filter) - found_attrs = entries[0].data.keys() + found_attrs = set(entries[0].data.keys()) + if search_suffix == DN_ROOT and "nsUniqueId" in found_attrs: + found_attrs.remove("nsUniqueId") if add_attr == '*': assert set(expected_attrs) - set(found_attrs) == set() diff --git a/dirsrvtests/tests/suites/mapping_tree/acceptance_test.py b/dirsrvtests/tests/suites/mapping_tree/acceptance_test.py new file mode 100644 index 000000000..387c313ad --- /dev/null +++ b/dirsrvtests/tests/suites/mapping_tree/acceptance_test.py @@ -0,0 +1,65 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2020 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- +# +import ldap +import logging +import pytest +import os +from lib389._constants import * +from lib389.topologies import topology_st as topo +from lib389.mappingTree import MappingTrees + +DEBUGGING = os.getenv("DEBUGGING", default=False) +if DEBUGGING: + logging.getLogger(__name__).setLevel(logging.DEBUG) +else: + logging.getLogger(__name__).setLevel(logging.INFO) +log = logging.getLogger(__name__) + + +def test_invalid_mt(topo): + """Test that you can not add a new suffix/mapping tree + that does not already have the backend entry created. + + :id: caabd407-f541-4695-b13f-8f92af1112a0 + :setup: Standalone Instance + :steps: + 1. Create a new suffix that specifies an existing backend which has a + different suffix. + 2. Create a suffix that has no backend entry at all. + :expectedresults: + 1. Should fail with UNWILLING_TO_PERFORM + 1. Should fail with UNWILLING_TO_PERFORM + """ + + bad_suffix = 'dc=does,dc=not,dc=exist' + mts = MappingTrees(topo.standalone) + + properties = { + 'cn': bad_suffix, + 'nsslapd-state': 'backend', + 'nsslapd-backend': 'userroot', + } + with pytest.raises(ldap.UNWILLING_TO_PERFORM): + mts.create(properties=properties) + + properties = { + 'cn': bad_suffix, + 'nsslapd-state': 'backend', + 'nsslapd-backend': 'notCreatedRoot', + } + with pytest.raises(ldap.UNWILLING_TO_PERFORM): + mts.create(properties=properties) + + +if __name__ == '__main__': + # Run isolated + # -s for DEBUG mode + CURRENT_FILE = os.path.realpath(__file__) + pytest.main(["-s", CURRENT_FILE]) + diff --git a/dirsrvtests/tests/suites/mapping_tree/be_del_and_default_naming_attr_test.py b/dirsrvtests/tests/suites/mapping_tree/be_del_and_default_naming_attr_test.py index 34a2de2ad..c25d89cb0 100644 --- a/dirsrvtests/tests/suites/mapping_tree/be_del_and_default_naming_attr_test.py +++ b/dirsrvtests/tests/suites/mapping_tree/be_del_and_default_naming_attr_test.py @@ -6,6 +6,8 @@ from lib389.topologies import topology_m1 as topo from lib389.backend import Backends from lib389.encrypted_attributes import EncryptedAttrs +pytestmark = pytest.mark.tier1 + DEBUGGING = os.getenv("DEBUGGING", default=False) if DEBUGGING: logging.getLogger(__name__).setLevel(logging.DEBUG) @@ -26,13 +28,13 @@ def test_be_delete(topo): :steps: 1. Create second backend/suffix 2. Add an encrypted attribute to the default suffix - 2. Delete default suffix - 3. Check the nsslapd-defaultnamingcontext is updated - 4. Delete the last backend - 5. Check the namingcontext has not changed - 6. Add new backend - 7. Set default naming context - 8. Verify the naming context is correct + 3. Delete default suffix + 4. Check the nsslapd-defaultnamingcontext is updated + 5. Delete the last backend + 6. Check the namingcontext has not changed + 7. Add new backend + 8. Set default naming context + 9. Verify the naming context is correct :expectedresults: 1. Success 2. Success @@ -42,6 +44,7 @@ def test_be_delete(topo): 6. Success 7. Success 8. Success + 9. Success """ inst = topo.ms["master1"] diff --git a/dirsrvtests/tests/suites/password/pwdPolicy_attribute_test.py b/dirsrvtests/tests/suites/password/pwdPolicy_attribute_test.py index b37eff70f..882faf513 100644 --- a/dirsrvtests/tests/suites/password/pwdPolicy_attribute_test.py +++ b/dirsrvtests/tests/suites/password/pwdPolicy_attribute_test.py @@ -99,6 +99,7 @@ def test_pwd_reset(topology_st, create_user): # Reset user's password our_user = UserAccount(topology_st.standalone, TEST_USER_DN) our_user.replace('userpassword', PASSWORD) + time.sleep(.5) # Check that pwdReset is TRUE assert our_user.get_attr_val_utf8('pwdReset') == 'TRUE' @@ -106,6 +107,7 @@ def test_pwd_reset(topology_st, create_user): # Bind as user and change its own password our_user.rebind(PASSWORD) our_user.replace('userpassword', PASSWORD) + time.sleep(.5) # Check that pwdReset is FALSE topology_st.standalone.simple_bind_s(DN_DM, PASSWORD) @@ -114,6 +116,9 @@ def test_pwd_reset(topology_st, create_user): # Reset password policy config topology_st.standalone.config.replace('passwordMustChange', 'off') + # Reset user's password + our_user.replace('userpassword', TEST_USER_PWD) + @pytest.mark.parametrize('subtree_pwchange,user_pwchange,exception', [('on', 'off', ldap.UNWILLING_TO_PERFORM), @@ -171,7 +176,7 @@ def test_change_pwd(topology_st, create_user, password_policy, user.reset_password('new_pass') except ldap.LDAPError as e: log.error('Failed to change userpassword for {}: error {}'.format( - TEST_USER_DN, e.message['info'])) + TEST_USER_DN, e.args[0['info']])) raise e finally: log.info('Bind as DM') @@ -245,7 +250,7 @@ def test_pwd_min_age(topology_st, create_user, password_policy): user.reset_password(TEST_USER_PWD) except ldap.LDAPError as e: log.error('Failed to change userpassword for {}: error {}'.format( - TEST_USER_DN, e.message['info'])) + TEST_USER_DN, e.args[0]['info'])) raise e finally: log.info('Bind as DM') diff --git a/dirsrvtests/tests/suites/replication/changelog_test.py b/dirsrvtests/tests/suites/replication/changelog_test.py index e395f0e7c..66599286f 100644 --- a/dirsrvtests/tests/suites/replication/changelog_test.py +++ b/dirsrvtests/tests/suites/replication/changelog_test.py @@ -367,7 +367,7 @@ def test_dsconf_dump_changelog_files_removed(topo): # primary condition before executing the core goal of this case : management of generated files. log.info("Use dsconf dump-changelog with invalid parameters") - cmdline=['python', '/usr/sbin/dsconf', instance_url, '-D', DN_DM, '-w', 'badpasswd', 'replication', 'dump-changelog'] + cmdline=['/usr/sbin/dsconf', instance_url, '-D', DN_DM, '-w', 'badpasswd', 'replication', 'dump-changelog'] log.info('Command used : %s' % cmdline) proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE) msg = proc.communicate() @@ -377,7 +377,7 @@ def test_dsconf_dump_changelog_files_removed(topo): # Now the core goal of the test case # Using dsconf replication changelog without -l option log.info('Use dsconf replication changelog without -l option: no generated ldif files should be present in %s ' % changelog_dir) - cmdline=['python', '/usr/sbin/dsconf', instance_url, '-D', DN_DM, '-w', PASSWORD, 'replication', 'dump-changelog'] + cmdline=['/usr/sbin/dsconf', instance_url, '-D', DN_DM, '-w', PASSWORD, 'replication', 'dump-changelog'] log.info('Command used : %s' % cmdline) proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE) proc.communicate() @@ -396,7 +396,7 @@ def test_dsconf_dump_changelog_files_removed(topo): # Using dsconf replication changelog without -l option log.info('Use dsconf replication changelog with -l option: generated ldif files should be kept in %s ' % changelog_dir) - cmdline=['python', '/usr/sbin/dsconf', instance_url, '-D', DN_DM, '-w', PASSWORD, 'replication', 'dump-changelog', '-l'] + cmdline=['/usr/sbin/dsconf', instance_url, '-D', DN_DM, '-w', PASSWORD, 'replication', 'dump-changelog', '-l'] log.info('Command used : %s' % cmdline) proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE) proc.communicate() diff --git a/dirsrvtests/tests/suites/replication/conflict_resolve_test.py b/dirsrvtests/tests/suites/replication/conflict_resolve_test.py index 48d0067db..ea3eacc48 100644 --- a/dirsrvtests/tests/suites/replication/conflict_resolve_test.py +++ b/dirsrvtests/tests/suites/replication/conflict_resolve_test.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2018 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -117,7 +117,7 @@ def _test_base(topology): M1 = topology.ms["master1"] conts = nsContainers(M1, SUFFIX) - base_m2 = conts.create(properties={'cn': 'test_container'}) + base_m2 = conts.ensure_state(properties={'cn': 'test_container'}) for inst in topology: inst.config.loglevel([ErrorLog.DEFAULT, ErrorLog.REPLICA], service='error') diff --git a/dirsrvtests/tests/suites/replication/rfc2307compat.py b/dirsrvtests/tests/suites/replication/rfc2307compat.py new file mode 100644 index 000000000..ec98e9dac --- /dev/null +++ b/dirsrvtests/tests/suites/replication/rfc2307compat.py @@ -0,0 +1,174 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2020 Red Hat, Inc. +# Copyright (C) 2020 William Brown +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- +# +import pytest +from lib389.replica import Replicas +from lib389.tasks import * +from lib389.utils import * +from lib389.topologies import topology_m2 as topo_m2 +from . import get_repl_entries +from lib389.idm.user import UserAccount +from lib389.replica import ReplicationManager +from lib389._constants import * + +pytestmark = pytest.mark.tier0 + +TEST_ENTRY_NAME = 'mmrepl_test' +TEST_ENTRY_DN = 'uid={},{}'.format(TEST_ENTRY_NAME, DEFAULT_SUFFIX) +NEW_SUFFIX_NAME = 'test_repl' +NEW_SUFFIX = 'o={}'.format(NEW_SUFFIX_NAME) +NEW_BACKEND = 'repl_base' + +DEBUGGING = os.getenv("DEBUGGING", default=False) +if DEBUGGING: + logging.getLogger(__name__).setLevel(logging.DEBUG) +else: + logging.getLogger(__name__).setLevel(logging.INFO) +log = logging.getLogger(__name__) + +pytest.mark.skipif(not os.environ.get('UNSAFE_ACK', False), reason="UNSAFE tests may damage system configuration.") +def test_rfc2307compat(topo_m2): + """ Test to verify if 10rfc2307compat.ldif does not prevent replication of schema + - Create 2 masters and a test entry + - Move 10rfc2307compat.ldif to be private to M1 + - Move 10rfc2307.ldif to be private to M2 + - Add 'objectCategory' to the schema of M1 + - Force a replication session + - Check 'objectCategory' on M1 and M2 + """ + m1 = topo_m2.ms["master1"] + m2 = topo_m2.ms["master2"] + + m1.config.loglevel(vals=(ErrorLog.DEFAULT, ErrorLog.REPLICA)) + m2.config.loglevel(vals=(ErrorLog.DEFAULT, ErrorLog.REPLICA)) + + m1.add_s(Entry(( + TEST_ENTRY_DN, { + "objectClass": "top", + "objectClass": "extensibleObject", + 'uid': TEST_ENTRY_NAME, + 'cn': TEST_ENTRY_NAME, + 'sn': TEST_ENTRY_NAME, + } + ))) + + entries = get_repl_entries(topo_m2, TEST_ENTRY_NAME, ["uid"]) + assert all(entries), "Entry {} wasn't replicated successfully".format(TEST_ENTRY_DN) + + # Clean the old locations (if any) + m1_temp_schema = os.path.join(m1.get_config_dir(), 'schema') + m2_temp_schema = os.path.join(m2.get_config_dir(), 'schema') + m1_schema = os.path.join(m1.get_data_dir(), 'dirsrv/schema') + m1_opt_schema = os.path.join(m1.get_data_dir(), 'dirsrv/data') + m1_temp_backup = os.path.join(m1.get_tmp_dir(), 'schema') + + # Does the system schema exist? + if os.path.islink(m1_schema): + # Then we need to put the m1 schema back. + os.unlink(m1_schema) + shutil.copytree(m1_temp_backup, m1_schema) + if not os.path.exists(m1_temp_backup): + shutil.copytree(m1_schema, m1_temp_backup) + + shutil.rmtree(m1_temp_schema, ignore_errors=True) + shutil.rmtree(m2_temp_schema, ignore_errors=True) + + # Build a new copy + shutil.copytree(m1_schema, m1_temp_schema) + shutil.copytree(m1_schema, m2_temp_schema) + # Ensure 99user.ldif exists + with open(os.path.join(m1_temp_schema, '99user.ldif'), 'w') as f: + f.write('dn: cn=schema') + + with open(os.path.join(m2_temp_schema, '99user.ldif'), 'w') as f: + f.write('dn: cn=schema') + + # m1 has compat, m2 has legacy. + os.unlink(os.path.join(m2_temp_schema, '10rfc2307compat.ldif')) + shutil.copy(os.path.join(m1_opt_schema, '10rfc2307.ldif'), m2_temp_schema) + + # Configure the instances + # m1.config.replace('nsslapd-schemadir', m1_temp_schema) + # m2.config.replace('nsslapd-schemadir', m2_temp_schema) + + # Now mark the system schema as empty. + shutil.rmtree(m1_schema) + os.symlink('/var/lib/empty', m1_schema) + + print("SETUP COMPLETE -->") + + # Stop all instances + m1.stop() + m2.stop() + + # udpate the schema on M1 to tag a schemacsn + m1.start() + objectcategory_attr = '( NAME \'objectCategory\' DESC \'test of objectCategory\' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )' + m1.schema.add_schema('attributetypes', [ensure_bytes(objectcategory_attr)]) + + # Now start M2 and trigger a replication M1->M2 + m2.start() + m1.modify_s(TEST_ENTRY_DN, [(ldap.MOD_ADD, 'cn', [ensure_bytes('value_m1')])]) + + # Now check that objectCategory is in both schema + time.sleep(10) + ents = m1.search_s("cn=schema", ldap.SCOPE_SUBTREE, 'objectclass=*',['attributetypes']) + for value in ents[0].getValues('attributetypes'): + if ensure_bytes('objectCategory') in value: + log.info("M1: " + str(value)) + break + assert ensure_bytes('objectCategory') in value + + ents = m2.search_s("cn=schema", ldap.SCOPE_SUBTREE, 'objectclass=*',['attributetypes']) + for value in ents[0].getValues('attributetypes'): + if ensure_bytes('objectCategory') in value: + log.info("M2: " + str(value)) + break + assert ensure_bytes('objectCategory') in value + + # Stop m2 + m2.stop() + + # "Update" it's schema, + os.unlink(os.path.join(m2_temp_schema, '10rfc2307.ldif')) + shutil.copy(os.path.join(m1_temp_backup, '10rfc2307compat.ldif'), m2_temp_schema) + + # Add some more to m1 + objectcategory_attr = '( NAME \'objectCategoryX\' DESC \'test of objectCategoryX\' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )' + m1.schema.add_schema('attributetypes', [ensure_bytes(objectcategory_attr)]) + + # Start m2. + m2.start() + m1.modify_s(TEST_ENTRY_DN, [(ldap.MOD_ADD, 'cn', [ensure_bytes('value_m2')])]) + + time.sleep(10) + ents = m1.search_s("cn=schema", ldap.SCOPE_SUBTREE, 'objectclass=*',['attributetypes']) + for value in ents[0].getValues('attributetypes'): + if ensure_bytes('objectCategoryX') in value: + log.info("M1: " + str(value)) + break + assert ensure_bytes('objectCategoryX') in value + + ents = m2.search_s("cn=schema", ldap.SCOPE_SUBTREE, 'objectclass=*',['attributetypes']) + for value in ents[0].getValues('attributetypes'): + if ensure_bytes('objectCategoryX') in value: + log.info("M2: " + str(value)) + break + assert ensure_bytes('objectCategoryX') in value + + # Success cleanup + os.unlink(m1_schema) + shutil.copytree(m1_temp_backup, m1_schema) + + +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/roles/__init__.py b/dirsrvtests/tests/suites/roles/__init__.py new file mode 100644 index 000000000..1981985fb --- /dev/null +++ b/dirsrvtests/tests/suites/roles/__init__.py @@ -0,0 +1,3 @@ +""" + :Requirement: 389-ds-base: Roles +""" diff --git a/dirsrvtests/tests/suites/roles/basic_test.py b/dirsrvtests/tests/suites/roles/basic_test.py index 3f1b7568c..47a531794 100644 --- a/dirsrvtests/tests/suites/roles/basic_test.py +++ b/dirsrvtests/tests/suites/roles/basic_test.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2019 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -36,18 +36,19 @@ FILTERROLEENGROLE = "cn=FILTERROLEENGROLE,{}".format(DNBASE) def test_filterrole(topo): - ''' - :id: 8ada4064-786b-11e8-8634-8c16451d917b - :setup: server - :steps: - 1. Add test entry - 2. Add ACI - 3. Search nsconsole role - :expectedresults: - 1. Entry should be added - 2. Operation should succeed - 3. Operation should succeed - ''' + """Test Filter Role + + :id: 8ada4064-786b-11e8-8634-8c16451d917b + :setup: server + :steps: + 1. Add test entry + 2. Add ACI + 3. Search nsconsole role + :expectedresults: + 1. Entry should be added + 2. Operation should succeed + 3. Operation should succeed + """ Organization(topo.standalone).create(properties={"o": "acivattr"}, basedn=DEFAULT_SUFFIX) properties = { 'ou': 'eng', @@ -137,18 +138,19 @@ def test_filterrole(topo): def test_managedrole(topo): - ''' - :id: d52a9c00-3bf6-11e9-9b7b-8c16451d917b - :setup: server - :steps: - 1. Add test entry - 2. Add ACI - 3. Search managed role entries - :expectedresults: - 1. Entry should be added - 2. Operation should succeed - 3. Operation should succeed - ''' + """Test Managed Role + + :id: d52a9c00-3bf6-11e9-9b7b-8c16451d917b + :setup: server + :steps: + 1. Add test entry + 2. Add ACI + 3. Search managed role entries + :expectedresults: + 1. Entry should be added + 2. Operation should succeed + 3. Operation should succeed + """ # Create Managed role entry roles = ManagedRoles(topo.standalone, DEFAULT_SUFFIX) role = roles.create(properties={"cn": 'ROLE1'}) @@ -184,8 +186,12 @@ def test_managedrole(topo): # Set an aci that will deny ROLE1 manage role Domain(topo.standalone, DEFAULT_SUFFIX).\ - add('aci', '(targetattr=*)(version 3.0; aci "role aci";' + add('aci', '(targetattr="*")(version 3.0; aci "role aci";' ' deny(all) roledn="ldap:///{}";)'.format(role.dn),) + # Add self user modification and anonymous aci + ANON_ACI = "(targetattr=\"*\")(version 3.0; acl \"Anonymous Read access\"; allow (read,search,compare) userdn = \"ldap:///anyone\";)" + suffix = Domain(topo.standalone, DEFAULT_SUFFIX) + suffix.add('aci', ANON_ACI) # Crate a connection with cn=Fail which is member of ROLE1 conn = UserAccount(topo.standalone, "uid=Fail,{}".format(DEFAULT_SUFFIX)).bind(PW_DM) @@ -232,17 +238,18 @@ def _final(request, topo): def test_nestedrole(topo, _final): - """ - :id: 867b40c0-7fcf-4332-afc7-bd01025b77f2 - :setup: Standalone server - :steps: - 1. Add test entry - 2. Add ACI - 3. Search managed role entries - :expectedresults: - 1. Entry should be added - 2. Operation should succeed - 3. Operation should succeed + """Test Nested Role + + :id: 867b40c0-7fcf-4332-afc7-bd01025b77f2 + :setup: Standalone server + :steps: + 1. Add test entry + 2. Add ACI + 3. Search managed role entries + :expectedresults: + 1. Entry should be added + 2. Operation should succeed + 3. Operation should succeed """ # Create Managed role entry managed_roles = ManagedRoles(topo.standalone, DEFAULT_SUFFIX) @@ -271,7 +278,7 @@ def test_nestedrole(topo, _final): # Create a ACI with deny access to nested role entry Domain(topo.standalone, DEFAULT_SUFFIX).\ - add('aci', f'(targetattr=*)(version 3.0; aci ' + add('aci', f'(targetattr="*")(version 3.0; aci ' f'"role aci"; deny(all) roledn="ldap:///{nested_role.dn}";)') # Create connection with 'uid=test_user_1,ou=People,dc=example,dc=com' member of managed_role1 diff --git a/dirsrvtests/tests/suites/sasl/regression_test.py b/dirsrvtests/tests/suites/sasl/regression_test.py index 2db76ce98..58ff9a225 100644 --- a/dirsrvtests/tests/suites/sasl/regression_test.py +++ b/dirsrvtests/tests/suites/sasl/regression_test.py @@ -1,15 +1,14 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2016 Red Hat, Inc. +# Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). # See LICENSE for details. # --- END COPYRIGHT BLOCK --- # -import base64 + import os import pytest -import subprocess from lib389.tasks import * from lib389.utils import * from lib389.topologies import topology_m2 @@ -48,7 +47,7 @@ def check_pems(confdir, mycacert, myservercert, myserverkey, notexist): log.info("\n######################### Check PEM files (%s, %s, %s)%s in %s ######################\n" % (mycacert, myservercert, myserverkey, notexist, confdir)) global cacert - cacert = '%s/%s.pem' % (confdir, mycacert) + cacert = f"{mycacert}.pem" if os.path.isfile(cacert): if notexist == "": log.info('%s is successfully generated.' % cacert) @@ -61,7 +60,7 @@ def check_pems(confdir, mycacert, myservercert, myserverkey, notexist): assert False else: log.info('%s is correctly not generated.' % cacert) - servercert = '%s/%s.pem' % (confdir, myservercert) + servercert = f"{myservercert}.pem" if os.path.isfile(servercert): if notexist == "": log.info('%s is successfully generated.' % servercert) @@ -74,7 +73,7 @@ def check_pems(confdir, mycacert, myservercert, myserverkey, notexist): assert False else: log.info('%s is correctly not generated.' % servercert) - serverkey = '%s/%s.pem' % (confdir, myserverkey) + serverkey = f"{myserverkey}.pem" if os.path.isfile(serverkey): if notexist == "": log.info('%s is successfully generated.' % serverkey) @@ -91,16 +90,16 @@ def check_pems(confdir, mycacert, myservercert, myserverkey, notexist): def relocate_pem_files(topology_m2): log.info("######################### Relocate PEM files on master1 ######################") - mycacert = 'MyCA' + certdir_prefix = "/dev/shm" + mycacert = os.path.join(certdir_prefix, "MyCA") topology_m2.ms["master1"].encryption.set('CACertExtractFile', mycacert) - myservercert = 'MyServerCert1' - myserverkey = 'MyServerKey1' + myservercert = os.path.join(certdir_prefix, "MyServerCert1") + myserverkey = os.path.join(certdir_prefix, "MyServerKey1") topology_m2.ms["master1"].rsa.apply_mods([(ldap.MOD_REPLACE, 'ServerCertExtractFile', myservercert), (ldap.MOD_REPLACE, 'ServerKeyExtractFile', myserverkey)]) log.info("##### restart master1") topology_m2.ms["master1"].restart() - m1confdir = topology_m2.ms["master1"].confdir - check_pems(m1confdir, mycacert, myservercert, myserverkey, "") + check_pems(certdir_prefix, mycacert, myservercert, myserverkey, "") @pytest.mark.ds47536 def test_openldap_no_nss_crypto(topology_m2): diff --git a/dirsrvtests/tests/suites/syncrepl_plugin/__init__.py b/dirsrvtests/tests/suites/syncrepl_plugin/__init__.py new file mode 100644 index 000000000..699d58f79 --- /dev/null +++ b/dirsrvtests/tests/suites/syncrepl_plugin/__init__.py @@ -0,0 +1,163 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2020 William Brown +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- + +import logging +import ldap +import time +from ldap.syncrepl import SyncreplConsumer +import pytest +from lib389 import DirSrv +from lib389.idm.user import nsUserAccounts, UserAccounts +from lib389.topologies import topology_st as topology +from lib389.paths import Paths +from lib389.utils import ds_is_older +from lib389.plugins import RetroChangelogPlugin, ContentSynchronizationPlugin +from lib389._constants import * + +log = logging.getLogger(__name__) + +class ISyncRepl(DirSrv, SyncreplConsumer): + """ + This implements a test harness for checking syncrepl, and allowing us to check various actions or + behaviours. During a "run" it stores the results in it's instance, so that they can be inspected + later to ensure that syncrepl worked as expected. + """ + def __init__(self, inst, openldap=False): + self.inst = inst + self.msgid = None + + self.last_cookie = None + self.next_cookie = None + self.cookie = None + self.openldap = openldap + if self.openldap: + # In openldap mode, our initial cookie needs to be a rid. + self.cookie = "rid=123" + self.delete = [] + self.present = [] + self.entries = {} + + super().__init__() + + def result4(self, *args, **kwargs): + return self.inst.result4(*args, **kwargs, escapehatch='i am sure') + + def search_ext(self, *args, **kwargs): + return self.inst.search_ext(*args, **kwargs, escapehatch='i am sure') + + def syncrepl_search(self, base=DEFAULT_SUFFIX, scope=ldap.SCOPE_SUBTREE, mode='refreshOnly', cookie=None, **search_args): + # Wipe the last result set. + self.delete = [] + self.present = [] + self.entries = {} + self.next_cookie = None + # Start the sync + # If cookie is none, will call "get_cookie" we have. + self.msgid = super().syncrepl_search(base, scope, mode, cookie, **search_args) + log.debug(f'syncrepl_search -> {self.msgid}') + assert self.msgid is not None + + def syncrepl_complete(self): + log.debug(f'syncrepl_complete -> {self.msgid}') + assert self.msgid is not None + # Loop until the operation is complete. + while super().syncrepl_poll(msgid=self.msgid) is True: + pass + assert self.next_cookie is not None + self.last_cookie = self.cookie + self.cookie = self.next_cookie + + def check_cookie(self): + assert self.last_cookie != self.cookie + + def syncrepl_set_cookie(self, cookie): + log.debug(f'set_cookie -> {cookie}') + if self.openldap: + assert self.cookie.startswith("rid=123") + self.next_cookie = cookie + + def syncrepl_get_cookie(self): + log.debug('get_cookie -> %s' % self.cookie) + if self.openldap: + assert self.cookie.startswith("rid=123") + return self.cookie + + def syncrepl_present(self, uuids, refreshDeletes=False): + log.debug(f'=====> refdel -> {refreshDeletes} uuids -> {uuids}') + if uuids is not None: + self.present = self.present + uuids + + def syncrepl_delete(self, uuids): + log.debug(f'delete -> {uuids}') + self.delete = uuids + + def syncrepl_entry(self, dn, attrs, uuid): + log.debug(f'entry -> {dn}') + self.entries[dn] = (uuid, attrs) + + def syncrepl_refreshdone(self): + log.debug('refreshdone') + +def syncstate_assert(st, sync): + # How many entries do we have? + r = st.search_ext_s( + base=DEFAULT_SUFFIX, + scope=ldap.SCOPE_SUBTREE, + filterstr='(objectClass=*)', + attrsonly=1, + escapehatch='i am sure' + ) + + # Initial sync + log.debug("*test* initial") + sync.syncrepl_search() + sync.syncrepl_complete() + # check we caught them all + assert len(r) == len(sync.entries.keys()) + assert len(r) == len(sync.present) + assert 0 == len(sync.delete) + + # Add a new entry + + account = nsUserAccounts(st, DEFAULT_SUFFIX).create_test_user() + # Check + log.debug("*test* add") + sync.syncrepl_search() + sync.syncrepl_complete() + sync.check_cookie() + assert 1 == len(sync.entries.keys()) + assert 1 == len(sync.present) + assert 0 == len(sync.delete) + + # Mod + account.replace('description', 'change') + # Check + log.debug("*test* mod") + sync.syncrepl_search() + sync.syncrepl_complete() + sync.check_cookie() + assert 1 == len(sync.entries.keys()) + assert 1 == len(sync.present) + assert 0 == len(sync.delete) + + ## Delete + account.delete() + + # Check + log.debug("*test* del") + sync.syncrepl_search() + sync.syncrepl_complete() + # In a delete, the cookie isn't updated (?) + sync.check_cookie() + log.debug(f'{sync.entries.keys()}') + log.debug(f'{sync.present}') + log.debug(f'{sync.delete}') + assert 0 == len(sync.entries.keys()) + assert 0 == len(sync.present) + assert 1 == len(sync.delete) + diff --git a/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py b/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py index 7b35537d5..64b7425a5 100644 --- a/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py +++ b/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py @@ -20,7 +20,7 @@ from lib389.idm.group import Groups from lib389.topologies import topology_st as topology from lib389.paths import Paths from lib389.utils import ds_is_older -from lib389.plugins import RetroChangelogPlugin, ContentSyncPlugin, AutoMembershipPlugin, MemberOfPlugin, MemberOfSharedConfig, AutoMembershipDefinitions, MEPTemplates, MEPConfigs, ManagedEntriesPlugin, MEPTemplate +from lib389.plugins import RetroChangelogPlugin, ContentSynchronizationPlugin, AutoMembershipPlugin, MemberOfPlugin, MemberOfSharedConfig, AutoMembershipDefinitions, MEPTemplates, MEPConfigs, ManagedEntriesPlugin, MEPTemplate from lib389._constants import * from . import ISyncRepl, syncstate_assert @@ -54,7 +54,7 @@ def test_syncrepl_basic(topology): # Set the default targetid rcl.replace('nsslapd-attribute', 'nsuniqueid:targetUniqueId') # Enable sync repl - csp = ContentSyncPlugin(st) + csp = ContentSynchronizationPlugin(st) csp.enable() # Restart DS st.restart() @@ -176,7 +176,7 @@ def test_sync_repl_mep(topology, request): plugin.set('nsslapd-attribute', 'nsuniqueid:targetuniqueid') # Enable sync plugin - plugin = ContentSyncPlugin(inst) + plugin = ContentSynchronizationPlugin(inst) plugin.enable() # Check the plug-in status @@ -232,6 +232,8 @@ def test_sync_repl_mep(topology, request): prev = int(cookie) sync_repl.join() log.info('test_sync_repl_map: PASS\n') + inst.start() + def test_sync_repl_cookie(topology, request): """Test sync_repl cookie are progressing is an increasing order @@ -240,33 +242,33 @@ def test_sync_repl_cookie(topology, request): :id: d7fbde25-5702-46ac-b38e-169d7a68e97c :setup: Standalone Instance :steps: - 1.: enable retroCL - 2.: configure retroCL to log nsuniqueid as targetUniqueId - 3.: enable content_sync plugin - 4.: enable automember - 5.: create (2) groups. Few groups can help to reproduce the concurrent updates problem. - 6.: configure automember to provision those groups with 'member' - 7.: enable and configure memberof plugin - 8.: enable plugin log level - 9.: restart the server - 10.: create a thread dedicated to run a sync repl client - 11.: Create (9) users that will generate nested updates (automember/memberof) - 12.: stop sync repl client and collect the list of cookie.change_no - 13.: check that cookies.change_no are in increasing order + 1. enable retroCL + 2. configure retroCL to log nsuniqueid as targetUniqueId + 3. enable content_sync plugin + 4. enable automember + 5. create (2) groups. Few groups can help to reproduce the concurrent updates problem. + 6. configure automember to provision those groups with 'member' + 7. enable and configure memberof plugin + 8. enable plugin log level + 9. restart the server + 10. create a thread dedicated to run a sync repl client + 11. Create (9) users that will generate nested updates (automember/memberof) + 12. stop sync repl client and collect the list of cookie.change_no + 13. check that cookies.change_no are in increasing order :expectedresults: - 1.: succeeds - 2.: succeeds - 3.: succeeds - 4.: succeeds - 5.: succeeds - 6.: succeeds - 7.: succeeds - 8.: succeeds - 9.: succeeds - 10.: succeeds - 11.: succeeds - 12.: succeeds - 13.: succeeds + 1. succeeds + 2. succeeds + 3. succeeds + 4. succeeds + 5. succeeds + 6. succeeds + 7. succeeds + 8. succeeds + 9. succeeds + 10. succeeds + 11. succeeds + 12. succeeds + 13. succeeds """ inst = topology[0] @@ -277,7 +279,7 @@ def test_sync_repl_cookie(topology, request): plugin.set('nsslapd-attribute', 'nsuniqueid:targetuniqueid') # Enable sync plugin - plugin = ContentSyncPlugin(inst) + plugin = ContentSynchronizationPlugin(inst) plugin.enable() # Enable automember @@ -409,7 +411,7 @@ def test_sync_repl_cookie_add_del(topology, request): plugin.set('nsslapd-attribute', 'nsuniqueid:targetuniqueid') # Enable sync plugin - plugin = ContentSyncPlugin(inst) + plugin = ContentSynchronizationPlugin(inst) plugin.enable() # Enable automember @@ -541,7 +543,7 @@ def test_sync_repl_cookie_with_failure(topology, request): plugin.set('nsslapd-attribute', 'nsuniqueid:targetuniqueid') # Enable sync plugin - plugin = ContentSyncPlugin(inst) + plugin = ContentSynchronizationPlugin(inst) plugin.enable() # Enable automember diff --git a/dirsrvtests/tests/suites/vlv/regression_test.py b/dirsrvtests/tests/suites/vlv/regression_test.py index 646cd97ba..2e1637a21 100644 --- a/dirsrvtests/tests/suites/vlv/regression_test.py +++ b/dirsrvtests/tests/suites/vlv/regression_test.py @@ -84,8 +84,8 @@ def test_bulk_import_when_the_backend_with_vlv_was_recreated(topology_m2): MappingTrees(M2).list()[0].delete() Backends(M2).list()[0].delete() # Recreate the backend and the VLV index on Master 2. - M2.mappingtree.create(DEFAULT_SUFFIX, "userRoot") M2.backend.create(DEFAULT_SUFFIX, {BACKEND_NAME: "userRoot"}) + M2.mappingtree.create(DEFAULT_SUFFIX, "userRoot") # Recreating vlvSrchDn and vlvIndexDn on Master 2. vlv_searches.create( basedn="cn=userRoot,cn=ldbm database,cn=plugins,cn=config", -- 2.26.2