From 459f73835de1be34bd9c9f1636ade92fd884d9ca Mon Sep 17 00:00:00 2001 From: Anuj Borah Date: Feb 20 2019 02:44:30 +0000 Subject: Issue: 50112 - Port ACI test suit from TET to python3(modify) Port ACI test suit from TET to python3(modify) https://pagure.io/389-ds-base/issue/50112 Reviewed by: William Brown --- diff --git a/dirsrvtests/tests/suites/acl/modify_test.py b/dirsrvtests/tests/suites/acl/modify_test.py new file mode 100644 index 0000000..8f9054b --- /dev/null +++ b/dirsrvtests/tests/suites/acl/modify_test.py @@ -0,0 +1,574 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2019 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK ---- + + +import pytest, os, ldap +from lib389._constants import DEFAULT_SUFFIX, PW_DM +from lib389.idm.user import UserAccount +from lib389.idm.account import Anonymous +from lib389.idm.group import Group, UniqueGroup +from lib389.idm.organizationalunit import OrganizationalUnit +from lib389.idm.group import Groups +from lib389.topologies import topology_st as topo +from lib389.idm.domain import Domain + + +CONTAINER_1_DELADD = "ou=Product Development,{}".format(DEFAULT_SUFFIX) +CONTAINER_2_DELADD = "ou=Accounting,{}".format(DEFAULT_SUFFIX) +USER_DELADD = "cn=Jeff Vedder,{}".format(CONTAINER_1_DELADD) +USER_WITH_ACI_DELADD = "cn=Sam Carter,{}".format(CONTAINER_2_DELADD) +KIRSTENVAUGHAN = "cn=Kirsten Vaughan, ou=Human Resources, {}".format(DEFAULT_SUFFIX) +HUMAN_OU_GLOBAL = "ou=Human Resources,{}".format(DEFAULT_SUFFIX) + + +@pytest.fixture(scope="function") +def cleanup_tree(request, topo): + + def fin(): + for i in [USER_DELADD, USER_WITH_ACI_DELADD, KIRSTENVAUGHAN, CONTAINER_1_DELADD, CONTAINER_2_DELADD, HUMAN_OU_GLOBAL]: + try: + UserAccount(topo.standalone, i).delete() + except: + pass + + request.addfinalizer(fin) + + +@pytest.fixture(scope="function") +def aci_of_user(request, topo): + aci_list = Domain(topo.standalone, DEFAULT_SUFFIX).get_attr_vals('aci') + + def finofaci(): + domain = Domain(topo.standalone, DEFAULT_SUFFIX) + domain.set('aci', None) + for i in aci_list: + domain.add("aci", i) + + request.addfinalizer(finofaci) + + +def test_allow_write_access_to_targetattr_with_a_single_attribute( + topo, aci_of_user, cleanup_tree): + """ + Modify Test 1 Allow write access to targetattr with a single attribute + :id:620d7b82-7abf-11e8-a4db-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 + """ + ACI_BODY = '(targetattr = "title")(version 3.0; acl "ACI NAME"; allow (write) (userdn = "ldap:///anyone") ;)' + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) + + ou = OrganizationalUnit(topo.standalone, "ou=Product Development,{}".format(DEFAULT_SUFFIX)) + ou.create(properties={'ou': 'Product Development'}) + + properties = { + 'uid': 'Jeff Vedder', + 'cn': 'Jeff Vedder', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'JeffVedder', + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, "cn=Jeff Vedder,ou=Product Development,{}".format(DEFAULT_SUFFIX)) + user.create(properties=properties) + + # Allow write access to targetattr with a single attribute + conn = Anonymous(topo.standalone).bind() + ua = UserAccount(conn, USER_DELADD) + ua.add("title", "Architect") + assert ua.get_attr_val('title') + ua.remove("title", "Architect") + + +def test_allow_write_access_to_targetattr_with_multiple_attibutes( + topo, aci_of_user, cleanup_tree): + """ + Modify Test 2 Allow write access to targetattr with multiple attibutes + :id:6b9f05c6-7abf-11e8-9ba1-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 + """ + ACI_BODY = '(targetattr = "telephonenumber || roomnumber")(version 3.0; acl "ACI NAME"; allow (write) (userdn = "ldap:///anyone") ;)' + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) + + ou = OrganizationalUnit(topo.standalone, "ou=Product Development,{}".format(DEFAULT_SUFFIX)) + ou.create(properties={'ou': 'Product Development'}) + + properties = { + 'uid': 'Jeff Vedder', + 'cn': 'Jeff Vedder', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'JeffVedder', + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, "cn=Jeff Vedder,ou=Product Development,{}".format(DEFAULT_SUFFIX)) + user.create(properties=properties) + + # Allow write access to targetattr with multiple attibutes + conn = Anonymous(topo.standalone).bind() + ua = UserAccount(conn, USER_DELADD) + ua.add("telephonenumber", "+1 408 555 1212") + assert ua.get_attr_val('telephonenumber') + ua.add("roomnumber", "101") + assert ua.get_attr_val('roomnumber') + + +def test_allow_write_access_to_userdn_all(topo, aci_of_user, cleanup_tree): + """ + Modify Test 3 Allow write access to userdn 'all' + :id:70c58818-7abf-11e8-afa1-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 + """ + ACI_BODY = '(targetattr = "*")(version 3.0; acl "ACI NAME"; allow (write) (userdn = "ldap:///all") ;)' + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) + + for i in ['Product Development', 'Accounting']: + ou = OrganizationalUnit(topo.standalone, "ou={},{}".format(i, DEFAULT_SUFFIX)) + ou.create(properties={'ou': i}) + + for i in ['Jeff Vedder,ou=Product Development', 'Sam Carter,ou=Accounting']: + properties = { + 'uid': i, + 'cn': i, + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + i, + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, "cn={},{}".format(i, DEFAULT_SUFFIX)) + user.create(properties=properties) + + # Allow write access to userdn 'all' + conn = Anonymous(topo.standalone).bind() + with pytest.raises(ldap.INSUFFICIENT_ACCESS): + UserAccount(conn, USER_DELADD).add("title", "Architect") + conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) + UserAccount(conn, USER_DELADD).add("title", "Architect") + assert UserAccount(conn, USER_DELADD).get_attr_val('title') + + +def test_allow_write_access_to_userdn_with_wildcards_in_dn( + topo, aci_of_user, cleanup_tree): + """ + Modify Test 4 Allow write access to userdn with wildcards in DN + :id:766c2312-7abf-11e8-b57d-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 + """ + ACI_BODY = '(targetattr = "*")(version 3.0; acl "ACI NAME"; allow (write)(userdn = "ldap:///cn=*, ou=Product Development,{}") ;)'.format(DEFAULT_SUFFIX) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) + + ou = OrganizationalUnit(topo.standalone, "ou=Product Development,{}".format(DEFAULT_SUFFIX)) + ou.create(properties={'ou': 'Product Development'}) + + properties = { + 'uid': 'Jeff Vedder', + 'cn': 'Jeff Vedder', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'JeffVedder', + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, "cn=Jeff Vedder,ou=Product Development,{}".format(DEFAULT_SUFFIX)) + user.create(properties=properties) + + conn = UserAccount(topo.standalone, USER_DELADD).bind(PW_DM) + # Allow write access to userdn with wildcards in DN + ua = UserAccount(conn, USER_DELADD) + ua.add("title", "Architect") + assert ua.get_attr_val('title') + + +def test_allow_write_access_to_userdn_with_multiple_dns(topo, aci_of_user, cleanup_tree): + """ + Modify Test 5 Allow write access to userdn with multiple DNs + :id:7aae760a-7abf-11e8-bc3a-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 + """ + ACI_BODY = '(targetattr = "*")(version 3.0; acl "ACI NAME"; allow (write)(userdn = "ldap:///{} || ldap:///{}") ;)'.format(USER_DELADD, USER_WITH_ACI_DELADD) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) + + for i in ['Product Development', 'Accounting', 'Human Resources']: + ou = OrganizationalUnit(topo.standalone, "ou={},{}".format(i, DEFAULT_SUFFIX)) + ou.create(properties={'ou': i}) + + for i in ['Jeff Vedder,ou=Product Development', 'Sam Carter,ou=Accounting', 'Kirsten Vaughan, ou=Human Resources']: + properties = { + 'uid': i, + 'cn': i, + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + i, + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, "cn={},{}".format(i, DEFAULT_SUFFIX)) + user.create(properties=properties) + + conn = UserAccount(topo.standalone, USER_DELADD).bind(PW_DM) + # Allow write access to userdn with multiple DNs + ua = UserAccount(conn, KIRSTENVAUGHAN) + ua.add("title", "Architect") + conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) + # Allow write access to userdn with multiple DNs + ua = UserAccount(conn, USER_DELADD) + ua.add("title", "Architect") + assert ua.get_attr_val('title') + + +def test_allow_write_access_to_target_with_wildcards(topo, aci_of_user, cleanup_tree): + """ + Modify Test 6 Allow write access to target with wildcards + :id:825fe884-7abf-11e8-8541-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 + """ + ACI_BODY = '(target = ldap:///{})(targetattr = "*")(version 3.0; acl "ACI NAME"; allow (write) (userdn = "ldap:///anyone") ;)'.format(DEFAULT_SUFFIX) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) + + for i in ['Product Development', 'Accounting', 'Human Resources']: + ou = OrganizationalUnit(topo.standalone, "ou={},{}".format(i, DEFAULT_SUFFIX)) + ou.create(properties={'ou': i}) + + for i in ['Jeff Vedder,ou=Product Development', 'Sam Carter,ou=Accounting', 'Kirsten Vaughan, ou=Human Resources']: + properties = { + 'uid': i, + 'cn': i, + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + i, + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, "cn={},{}".format(i, DEFAULT_SUFFIX)) + user.create(properties=properties) + + conn = UserAccount(topo.standalone, USER_DELADD).bind(PW_DM) + # Allow write access to target with wildcards + ua = UserAccount(conn, KIRSTENVAUGHAN) + ua.add("title", "Architect") + assert ua.get_attr_val('title') + conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) + # Allow write access to target with wildcards + ua = UserAccount(conn, USER_DELADD) + ua.add("title", "Architect") + assert ua.get_attr_val('title') + + +def test_allow_write_access_to_userdnattr(topo, aci_of_user, cleanup_tree): + """ + Modify Test 7 Allow write access to userdnattr + :id:86b418f6-7abf-11e8-ae28-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 + """ + ACI_BODY = '(target = ldap:///{})(targetattr=*)(version 3.0; acl "$tet_thistest";allow (write) (userdn = "ldap:///anyone"); )'.format(DEFAULT_SUFFIX) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) + + for i in ['Product Development', 'Accounting']: + ou = OrganizationalUnit(topo.standalone, "ou={},{}".format(i, DEFAULT_SUFFIX)) + ou.create(properties={'ou': i}) + + for i in ['Jeff Vedder,ou=Product Development', 'Sam Carter,ou=Accounting']: + properties = { + 'uid': i, + 'cn': i, + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + i, + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, "cn={},{}".format(i, DEFAULT_SUFFIX)) + user.create(properties=properties) + + UserAccount(topo.standalone, USER_WITH_ACI_DELADD).add('manager', USER_WITH_ACI_DELADD) + conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) + # Allow write access to userdnattr + ua = UserAccount(conn, USER_DELADD) + ua.add('uid', 'scoobie') + assert ua.get_attr_val('uid') + ua.add('uid', 'jvedder') + assert ua.get_attr_val('uid') + + +def test_allow_selfwrite_access_to_anyone(topo, aci_of_user, cleanup_tree): + """ + Modify Test 8 Allow selfwrite access to anyone + :id:8b3becf0-7abf-11e8-ac34-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 + """ + groups = Groups(topo.standalone, DEFAULT_SUFFIX) + group = groups.create(properties={"cn": "group1", + "description": "testgroup"}) + + ACI_BODY = '(target = ldap:///cn=group1,ou=Groups,{})(targetattr = "member")(version 3.0; acl "ACI NAME"; allow (selfwrite) (userdn = "ldap:///anyone") ;)'.format(DEFAULT_SUFFIX) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) + + ou = OrganizationalUnit(topo.standalone, "ou=Product Development,{}".format(DEFAULT_SUFFIX)) + ou.create(properties={'ou': 'Product Development'}) + + properties = { + 'uid': 'Jeff Vedder', + 'cn': 'Jeff Vedder', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'JeffVedder', + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, "cn=Jeff Vedder,ou=Product Development,{}".format(DEFAULT_SUFFIX)) + user.create(properties=properties) + + conn = UserAccount(topo.standalone, USER_DELADD).bind(PW_DM) + # Allow selfwrite access to anyone + groups = Groups(conn, DEFAULT_SUFFIX) + groups.list()[0].add_member(USER_DELADD) + group.delete() + + +def test_uniquemember_should_also_be_the_owner(topo, aci_of_user): + """ + Modify Test 10 groupdnattr = \"ldap:///$BASEDN?owner\" if owner is a group, group's + uniquemember should also be the owner + :id:9456b2d4-7abf-11e8-829d-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 + """ + for i in ['ACLGroupTest']: + ou = OrganizationalUnit(topo.standalone, "ou={},{}".format(i, DEFAULT_SUFFIX)) + ou.create(properties={'ou': i}) + + ou = OrganizationalUnit(topo.standalone, "ou=ACLDevelopment,{}".format(DEFAULT_SUFFIX)) + ou.create(properties={'ou': 'ACLDevelopment'}) + ou.set('aci','(targetattr="*")(version 3.0; acl "groupdnattr acl"; ' + 'allow (all)groupdnattr = "ldap:///{}?owner";)'.format(DEFAULT_SUFFIX)) + + grp = UniqueGroup(topo.standalone, "uid=anuj,ou=ACLDevelopment, {}".format(DEFAULT_SUFFIX)) + user_props = ( + {'sn': 'Borah', + 'cn': 'Anuj', + 'objectclass': ['top', 'person', 'organizationalPerson', 'inetOrgPerson', 'groupofUniquenames'], + 'userpassword': PW_DM, + 'givenname': 'Anuj', + 'ou': ['ACLDevelopment', 'People'], + 'roomnumber': '123', + 'uniquemember': 'cn=mandatory member' + } + ) + grp.create(properties=user_props) + + grp = UniqueGroup(topo.standalone, "uid=2ishani,ou=ACLDevelopment, {}".format(DEFAULT_SUFFIX)) + user_props = ( + {'sn': 'Borah', + 'cn': '2ishani', + 'objectclass': ['top', 'person','organizationalPerson', 'inetOrgPerson', 'groupofUniquenames'], + 'userpassword': PW_DM, + 'givenname': '2ishani', + 'ou': ['ACLDevelopment', 'People'], + 'roomnumber': '1234', + 'uniquemember': 'cn=mandatory member', "owner": "cn=group4, ou=ACLGroupTest, {}".format(DEFAULT_SUFFIX) + } + ) + grp.create(properties=user_props) + + grp = UniqueGroup(topo.standalone, 'cn=group1,ou=ACLGroupTest,'+DEFAULT_SUFFIX) + grp.create(properties={'cn': 'group1', + 'ou': 'groups'}) + grp.set('uniquemember', ["cn=group2, ou=ACLGroupTest, {}".format(DEFAULT_SUFFIX), + "cn=group3, ou=ACLGroupTest, {}".format(DEFAULT_SUFFIX)]) + + grp = UniqueGroup(topo.standalone, 'cn=group3,ou=ACLGroupTest,' + DEFAULT_SUFFIX) + grp.create(properties={'cn': 'group3', + 'ou': 'groups'}) + grp.set('uniquemember', ["cn=group4, ou=ACLGroupTest, {}".format(DEFAULT_SUFFIX)]) + + grp = UniqueGroup(topo.standalone, 'cn=group4,ou=ACLGroupTest,' + DEFAULT_SUFFIX) + grp.create(properties={ + 'cn': 'group4', + 'ou': 'groups'}) + grp.set('uniquemember', ["uid=anuj, ou=ACLDevelopment, {}".format(DEFAULT_SUFFIX)]) + + #uniquemember should also be the owner + conn = UserAccount(topo.standalone, "uid=anuj,ou=ACLDevelopment, {}".format(DEFAULT_SUFFIX)).bind(PW_DM) + ua = UserAccount(conn, "uid=2ishani, ou=ACLDevelopment, {}".format(DEFAULT_SUFFIX)) + ua.add('roomnumber', '9999') + assert ua.get_attr_val('roomnumber') + + for DN in ["cn=group4,ou=ACLGroupTest,{}".format(DEFAULT_SUFFIX), + "cn=group3,ou=ACLGroupTest,{}".format(DEFAULT_SUFFIX), + "cn=group1,ou=ACLGroupTest,{}".format(DEFAULT_SUFFIX), + "uid=2ishani,ou=ACLDevelopment,{}".format(DEFAULT_SUFFIX), + "uid=anuj,ou=ACLDevelopment,{}".format(DEFAULT_SUFFIX), "ou=ACLDevelopment,{}".format(DEFAULT_SUFFIX), + "ou=ACLGroupTest, {}".format(DEFAULT_SUFFIX)]: + UserAccount(topo.standalone, DN).delete() + + +def test_aci_with_both_allow_and_deny(topo, aci_of_user, cleanup_tree): + """ + Modify Test 12 aci with both allow and deny + :id:9dcfe902-7abf-11e8-86dc-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 + """ + ACI_BODY = '(targetattr = "*")(version 3.0; acl "ACI NAME"; deny (read, search)userdn = "ldap:///{}"; allow (all) userdn = "ldap:///{}" ;)'.format(USER_WITH_ACI_DELADD, USER_DELADD) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) + + for i in ['Product Development', 'Accounting']: + ou = OrganizationalUnit(topo.standalone, "ou={},{}".format(i, DEFAULT_SUFFIX)) + ou.create(properties={'ou': i}) + + for i in ['Jeff Vedder,ou=Product Development', 'Sam Carter,ou=Accounting']: + properties = { + 'uid': i, + 'cn': i, + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + i, + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, "cn={},{}".format(i, DEFAULT_SUFFIX)) + user.create(properties=properties) + + conn = UserAccount(topo.standalone, USER_DELADD).bind(PW_DM) + # aci with both allow and deny, testing allow + assert UserAccount(conn, USER_WITH_ACI_DELADD).get_attr_val('uid') + conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) + # aci with both allow and deny, testing deny + with pytest.raises(IndexError): + UserAccount(conn, USER_WITH_ACI_DELADD).get_attr_val('uid') + + +def test_allow_owner_to_modify_entry(topo, aci_of_user, cleanup_tree): + """ + Modify Test 14 allow userdnattr = owner to modify entry + :id:aa302090-7abf-11e8-811a-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 + """ + grp = UniqueGroup(topo.standalone, 'cn=intranet,' + DEFAULT_SUFFIX) + grp.create(properties={ + 'cn': 'intranet', + 'ou': 'groups'}) + grp.set('owner', USER_WITH_ACI_DELADD) + + ACI_BODY = '(target ="ldap:///cn=intranet, {}") (targetattr ="*")(targetfilter ="(objectclass=groupOfUniqueNames)") (version 3.0;acl "$tet_thistest";allow(read, write, delete, search, compare, add) (userdnattr = "owner");)'.format(DEFAULT_SUFFIX) + Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) + + for i in ['Product Development', 'Accounting']: + ou = OrganizationalUnit(topo.standalone, "ou={},{}".format(i, DEFAULT_SUFFIX)) + ou.create(properties={'ou': i}) + for i in ['Jeff Vedder,ou=Product Development', 'Sam Carter,ou=Accounting']: + properties = { + 'uid': i, + 'cn': i, + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + i, + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, "cn={},{}".format(i, DEFAULT_SUFFIX)) + user.create(properties=properties) + + conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) + # allow userdnattr = owner to modify entry + ua = UserAccount(conn, 'cn=intranet,dc=example,dc=com') + ua.set('uniquemember', "cn=Andy Walker, ou=Accounting,dc=example,dc=com") + assert ua.get_attr_val('uniquemember') + + +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 new file mode 100644 index 0000000..c395e0b --- /dev/null +++ b/dirsrvtests/tests/suites/acl/modrdn_test.py @@ -0,0 +1,298 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2019 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK ---- + +import pytest, os, ldap +from lib389._constants import DEFAULT_SUFFIX, PW_DM +from lib389.idm.user import UserAccount +from lib389.idm.account import Anonymous +from lib389.idm.group import Group, UniqueGroup +from lib389.idm.organizationalunit import OrganizationalUnit, OrganizationalUnits +from lib389.topologies import topology_st as topo +from lib389.idm.domain import Domain + + +CONTAINER_1_DELADD = "ou=Product Development,{}".format(DEFAULT_SUFFIX) +CONTAINER_2_DELADD = "ou=Accounting,{}".format(DEFAULT_SUFFIX) +USER_DELADD = "cn=Jeff Vedder,{}".format(CONTAINER_1_DELADD) +USER_WITH_ACI_DELADD = "cn=Sam Carter,{}".format(CONTAINER_2_DELADD) +DYNAMIC_MODRDN = "cn=Test DYNAMIC_MODRDN Group 70, {}".format(DEFAULT_SUFFIX) +SAM_DAMMY_MODRDN = "cn=Sam Carter1,ou=Accounting,{}".format(DEFAULT_SUFFIX) +TRAC340_MODRDN = "cn=TRAC340_MODRDN,{}".format(DEFAULT_SUFFIX) +NEWENTRY9_MODRDN = "cn=NEWENTRY9_MODRDN,{}".format("ou=People,{}".format(DEFAULT_SUFFIX)) +OU0_OU_MODRDN = "ou=OU0,{}".format(DEFAULT_SUFFIX) +OU2_OU_MODRDN = "ou=OU2,{}".format(DEFAULT_SUFFIX) + + +@pytest.fixture(scope="function") +def aci_of_user(request, topo): + aci_list = Domain(topo.standalone, DEFAULT_SUFFIX).get_attr_vals('aci') + + def finofaci(): + domain = Domain(topo.standalone, DEFAULT_SUFFIX) + domain.set('aci', None) + for i in aci_list: + domain.add("aci", i) + + request.addfinalizer(finofaci) + + +@pytest.fixture(scope="function") +def _add_user(request, topo): + ou = OrganizationalUnit(topo.standalone, 'ou=Product Development,{}'.format(DEFAULT_SUFFIX)) + ou.create(properties={'ou': 'Product Development'}) + + ou = OrganizationalUnit(topo.standalone, 'ou=Accounting,{}'.format(DEFAULT_SUFFIX)) + ou.create(properties={'ou': 'Accounting'}) + + groups = Group(topo.standalone, DYNAMIC_MODRDN) + group_properties = {"cn": "Test DYNAMIC_MODRDN Group 70", + "objectclass": ["top", 'groupofURLs'], + 'memberURL': 'ldap:///{}??base?(cn=*)'.format(USER_WITH_ACI_DELADD)} + groups.create(properties=group_properties) + + properties = { + 'uid': 'Jeff Vedder', + 'cn': 'Jeff Vedder', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'JeffVedder', + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, 'cn=Jeff Vedder,ou=Product Development,{}'.format(DEFAULT_SUFFIX)) + user.create(properties=properties) + + properties = { + 'uid': 'Sam Carter', + 'cn': 'Sam Carter', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'SamCarter', + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, 'cn=Sam Carter,ou=Accounting,{}'.format(DEFAULT_SUFFIX)) + user.create(properties=properties) + + def fin(): + for DN in [USER_DELADD,USER_WITH_ACI_DELADD,DYNAMIC_MODRDN,CONTAINER_2_DELADD,CONTAINER_1_DELADD]: + UserAccount(topo.standalone, DN).delete() + + request.addfinalizer(fin) + + +def test_allow_write_privilege_to_anyone(topo, _add_user, aci_of_user): + """ + Modrdn Test 1 Allow write privilege to anyone + :id: 4406f12e-7932-11e8-9dea-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 ' + '(write) (userdn = "ldap:///anyone");)'.format(DEFAULT_SUFFIX)) + conn = Anonymous(topo.standalone).bind() + # Allow write privilege to anyone + useraccount = UserAccount(conn, USER_WITH_ACI_DELADD) + useraccount.rename("cn=Jeff Vedder") + assert 'cn=Jeff Vedder,ou=Accounting,dc=example,dc=com' == useraccount.dn + useraccount = UserAccount(conn, "cn=Jeff Vedder,ou=Accounting,dc=example,dc=com") + useraccount.rename("cn=Sam Carter") + assert 'cn=Sam Carter,ou=Accounting,dc=example,dc=com' == useraccount.dn + + +def test_allow_write_privilege_to_dynamic_group_with_scope_set_to_base_in_ldap_url( + topo, _add_user, aci_of_user +): + """ + 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)) + 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) + useraccount.rename("cn=Jeffbo Vedder") + assert 'cn=Jeffbo Vedder,ou=Product Development,dc=example,dc=com' == useraccount.dn + useraccount = UserAccount(conn, "cn=Jeffbo Vedder,{}".format(CONTAINER_1_DELADD)) + useraccount.rename("cn=Jeff Vedder") + 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 + """ + 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)) + 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) + with pytest.raises(ldap.INSUFFICIENT_ACCESS): + 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 + """ + 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)) + properties = { + 'uid': 'Sam Carter1', + 'cn': 'Sam Carter1', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'SamCarter1' + } + user = UserAccount(topo.standalone, 'cn=Sam Carter1,ou=Accounting,{}'.format(DEFAULT_SUFFIX)) + user.create(properties=properties) + user.set("userPassword", "password") + conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) + # Test for write access to naming atributes + useraccount = UserAccount(conn, SAM_DAMMY_MODRDN) + with pytest.raises(ldap.INSUFFICIENT_ACCESS): + useraccount.rename("uid=Jeffbo Vedder") + UserAccount(topo.standalone, SAM_DAMMY_MODRDN).delete() + + +@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 + """ + properties = { + 'uid': 'NEWENTRY9_MODRDN', + 'cn': 'NEWENTRY9_MODRDN_People', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'NEWENTRY9_MODRDN' + } + user = UserAccount(topo.standalone, 'cn=NEWENTRY9_MODRDN,ou=People,{}'.format(DEFAULT_SUFFIX)) + user.create(properties=properties) + user.set("userPassword", "password") + user.set("telephoneNumber", "989898191") + user.set("mail", "anuj@anuj.com") + user.set("givenName", "givenName") + user.set("uid", "NEWENTRY9_MODRDN") + OrganizationalUnits(topo.standalone, DEFAULT_SUFFIX).get('People').add("aci", ['(targetattr = "*") ' + '(version 3.0;acl "admin";allow (all)(userdn = "ldap:///{}");)'.format(NEWENTRY9_MODRDN), + '(targetattr = "mail") (version 3.0;acl "deny_mail";deny (write)(userdn = "ldap:///anyone");)', + '(targetattr = "uid") (version 3.0;acl "allow uid";allow (write)(userdn = "ldap:///{}");)'.format(NEWENTRY9_MODRDN)]) + UserAccount(topo.standalone, NEWENTRY9_MODRDN).replace("userpassword", "Anuj") + useraccount = UserAccount(topo.standalone, NEWENTRY9_MODRDN) + useraccount.rename("uid=newrdnchnged") + assert 'uid=newrdnchnged,ou=People,dc=example,dc=com' == useraccount.dn + + +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 + """ + properties = { + 'uid': 'TRAC340_MODRDN', + 'cn': 'TRAC340_MODRDN', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'TRAC340_MODRDN' + } + user = UserAccount(topo.standalone, 'cn=TRAC340_MODRDN,{}'.format(DEFAULT_SUFFIX)) + user.create(properties=properties) + 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)) + conn = UserAccount(topo.standalone, TRAC340_MODRDN).bind(PW_DM) + assert OrganizationalUnits(conn, DEFAULT_SUFFIX).get('OU0') + # Test for renaming target entry + OrganizationalUnits(topo.standalone, DEFAULT_SUFFIX).get('OU0').rename("ou=OU1") + assert OrganizationalUnits(conn, DEFAULT_SUFFIX).get('OU1') + ou = OrganizationalUnit(topo.standalone, 'ou=OU2,{}'.format(DEFAULT_SUFFIX)) + ou.create(properties={'ou': 'OU2'}) + # Test for renaming target entry + OrganizationalUnits(topo.standalone, DEFAULT_SUFFIX).get('OU1').rename("ou=OU1", newsuperior=OU2_OU_MODRDN) + assert OrganizationalUnits(conn, DEFAULT_SUFFIX).get('OU1') + + +if __name__ == "__main__": + CURRENT_FILE = os.path.realpath(__file__) + pytest.main("-s -v %s" % CURRENT_FILE)