#50185 Issue: 50112 - Port ACI test suit from TET to python3(modify)
Closed 3 years ago by spichugi. Opened 5 years ago by aborah.
aborah/389-ds-base modify  into  master

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

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

Port ACI test suit from TET to python3(modify)

https://pagure.io/389-ds-base/issue/50112

Reviewed by: ???

There is already create test_user as part of UserAccounts or nsUserAccounts. Why do you define your own?

There is already create test_user as part of UserAccounts or nsUserAccounts. Why do you define your own?

This is just to adjust with the acis , as if you use create test_user as part of UserAccounts it will create one with uid= and for some of the acis i need cn= , thats why in some cases i am using
create_test_user from working_constans.py in.

Why not change the aci's to use uid instead ...?

rebased onto 00c5a5bf4217e7c855123540a54a9a04aee9461e

5 years ago

rebased onto 31a4748dca4cab8efdfed152e3eb00ae8095022a

5 years ago

@firstyear , i have removed whole working_constans.py now only generic create_test functions are there .

rebased onto bf44545f3c48bd0e9d0189b9fe68fb0818c63bf9

5 years ago

rebased onto 338946cef1adad1a10b8849e1f2d0aca9774de15

5 years ago

This is a weird pattern, DEFAULT_SUFFIX is a "Domain" type, not a "UserAccount", so I don't see what you are trying to assert here either.

Rather than trying to make everything one-liners, just do:

ua = UserAccount(conn, "uid= ....".format(...))
ua.bind()
ua.add('roomnumber', '9999')

Not that it matters, but the homedirectory would probably be /home/jvedder'

Saying this, you have two static strings, why are you con-catinating them?

Don't do long one-liners like this. Code needs to be readable.

Okay, STOP using UserAccount(inst, dn) on things that are not user accounts. There is an OrganisationalUnit type for this. Use the proper types and classes because this could break in ways you don't know yet.

Don't use raw modrdn

As this tests are about modrdn , how am i suppose to go ahead ?

The correct way to do this, is to add modrdn capability to _mapped_object.py, in DSLdapObject. Look at def rename in that file for an example of how it's done. It's basically the only place in the lib389 codebase I'll allow raw ldap calls because it is our abstraction layer.

I would also expect that the difference between "rename" and "modrdn" is clearly explained in the documentation of the DSLdapObject.

I know it seems annoying, but the issue here is we have TONS of legacy debt. I have spent literally years trying to un-bury us from this. This means that the hard way is sometimes the right way long term. Every time we allow a single bypass, you just make "William of the Future's" job harder. This is why I insist we take a little bit of extra time now to "do it right" because then we never have to fix it ever again.

PS: It looks like you may not need to because reading http://www.python-ldap.org/en/latest/reference/ldap.html?highlight=modrdn_s#ldap.LDAPObject.modrdn_s it looks like modrdn_s is actually emulated by rename anyway, so you can just use the existing DSLdapObject rename() function, with the appropriate flags because it does the same thing.

Don't do raw rename.

what about this one , instead modrdn you asked me to use rename , now i am asked not use raw rename ? how is it even possible .

Don't use raw rename_s on the dirsrv instance. Use rename on the mapped object type. For example code:

useraccount = UserAccounts(instance, DEFAULT_SUFFIX).get('william')
useraccount.rename('uid=claire')

That would rename "william" to "claire". To move the object in the tree you do:

useraccount.rename('uid=claire', 'ou=something else,%s' % DEFAULT_SUFFIX)

The raw renames on DirSrv are what I am saying not to use. I'm saying to use the abstractions in lib389's DSLdapObject which fix dumb ldap behaviour and annoying python issues.

rebased onto 805c384015cb69cb153b97186722454d0d430e7c

5 years ago

@firstyear , all changes are done as per your suggestion

rebased onto 82756a93fdec7d70c3ee7730dd3405792d944f66

5 years ago

rebased onto 9c2cf7335d30f65f2e45606e5aaa8ad9894d43d9

5 years ago

@firstyear , this one is ready , all changes are done as per your suggestion

Made this comment in another file, but you can probably inline this properties into the .create() because you never reuse the value.

you can just make userPassword a property rather than needing an extra .set operation.

Does this work without concat? You may be better to have:

ou.set('aci',
    'long one line aci'
    .format(things))

Space this out properly (each key on one line.

So you have this really large "per function fixture" right. You add and remove HEAPS of objects. But not all of them are used for every test.

Your fixture should delete everything, but each test should just create the limited set of aci and objects required. By setting up so much every single time, you are using more CPU time, you risk polluting the test environment (How can you be sure of what aci was in play?). You also may find you don'th need so many user account objects and aci definitions, because you are creating only what is needed per test.

So I think this fixture here should be broken down, and the required smaller pieces should be put into their relavent tests.

rebased onto 5d854cbe3a2fd0db19e42562c9985accf3e5aaf2

5 years ago

rebased onto ce339ef663e44a7cc122ff849d7376c052c541f9

5 years ago

So you have this really large "per function fixture" right. You add and remove HEAPS of objects. But not all of them are used for every test.
Your fixture should delete everything, but each test should just create the limited set of aci and objects required. By setting up so much every single time, you are using more CPU time, you risk polluting the test environment (How can you be sure of what aci was in play?). You also may find you don'th need so many user account objects and aci definitions, because you are creating only what is needed per test.
So I think this fixture here should be broken down, and the required smaller pieces should be put into their relavent tests.

I have remove the fixture you are saying about , but i must say that if singly test case fails in that script , all rest test cases will fail automatically , it will give "User already exists error"

@firstyear all other changes also done as per your suggestion

I don't think you need the call to raw_entry here. You are trying to prove the entry exists for the assert, but .get() won't work if the entry doesn't exist. Additionally, there is a .exists method too.

rebased onto d20f2a8a44d5d975b7c06172154e6cbe7cf93195

5 years ago

rebased onto d69a30be9097b499121539ec896053bf60056a56

5 years ago

@firstyear all changes also done as per your suggestion

rebased onto 551a9abd4e7ab4352a576b2abc62c08c72f9e473

5 years ago

Given the target is ldap:/// all, you don't need "name, ou=..." here. lib389 will do ldap escaping on values too, so it's pretty likely this will actually be getting escaped and the users are NOT created in the ou like you think they are .....

Format this properly please. One key:value per line. I think I said this before ....

Ignore the ldap:///all comment about ou and escaping, re-reading, I'm incorrect.

rebased onto d2e9b74a025405119a8b5511f777fe96d4cf234a

5 years ago

rebased onto 459f738

5 years ago

@firstyear all changes are done as per your suggestion

Pull-Request has been merged by firstyear

5 years ago

389-ds-base is moving from Pagure to Github. This means that new issues and pull requests
will be accepted only in 389-ds-base's github repository.

This pull request has been cloned to Github as issue and is available here:
- https://github.com/389ds/389-ds-base/issues/3244

If you want to continue to work on the PR, please navigate to the github issue,
download the patch from the attachments and file a new pull request.

Thank you for understanding. We apologize for all inconvenience.

Pull-Request has been closed by spichugi

3 years ago