def test_cannot_add_an_entry_with_attribute_values_we_are_not_allowed_add( 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)) "Valueacl Test $tet_thistest Test not allowed add an entry" :id:0d0effee-7aaa-11e8-b673-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 = '(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) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY) properties = { 'uid': 'FRED', 'cn': 'FRED', 'sn': 'user', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + 'FRED' } user = UserAccount(topo.standalone, 'cn=FRED,ou=Accounting,{}'.format(DEFAULT_SUFFIX)) user.create(properties=properties) user.set('title', ['anuj', 'kumar', 'borah']) conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM) # aci will not allow adding objectclass user = UserAccount(conn, USER_WITH_ACI_DELADD) with pytest.raises(ldap.INSUFFICIENT_ACCESS): user.add("objectclass", "person")
def test_csnpurge_large_valueset(topo_m2): """Test csn generator test :id: 63e2bdb2-0a8f-4660-9465-7b80a9f72a74 :setup: MMR with 2 masters :steps: 1. Create a test_user 2. add a large set of values (more than 10) 3. delete all the values (more than 10) 4. configure the replica to purge those values (purgedelay=5s) 5. Waiting for 6 second 6. do a series of update :expectedresults: 1. Should succeeds 2. Should succeeds 3. Should succeeds 4. Should succeeds 5. Should succeeds 6. Should not crash """ m1 = topo_m2.ms["master2"] test_user = UserAccount(m1, TEST_ENTRY_DN) if test_user.exists(): log.info('Deleting entry {}'.format(TEST_ENTRY_DN)) test_user.delete() test_user.create( properties={ 'uid': TEST_ENTRY_NAME, 'cn': TEST_ENTRY_NAME, 'sn': TEST_ENTRY_NAME, 'userPassword': TEST_ENTRY_NAME, 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/mmrepl_test', }) # create a large value set so that it is sorted for i in range(1, 20): test_user.add('description', 'value {}'.format(str(i))) # delete all values of the valueset for i in range(1, 20): test_user.remove('description', 'value {}'.format(str(i))) # set purging delay to 5 second and wait more that 5second replicas = Replicas(m1) replica = replicas.list()[0] log.info('nsds5ReplicaPurgeDelay to 5') replica.set('nsds5ReplicaPurgeDelay', '5') time.sleep(6) # add some new values to the valueset containing entries that should be purged for i in range(21, 25): test_user.add('description', 'value {}'.format(str(i)))
def test_password_repl_error(topo_m4, test_entry): """Check that error about userpassword replication is properly logged :ID: 714130ff-e4f0-4633-9def-c1f4b24abfef :feature: Multi master replication :setup: Four masters replication setup, a test entry :steps: 1. Change userpassword on master 1 2. Restart the servers to flush the logs 3. Check the error log for an replication error :expectedresults: We don't have a replication error in the error log """ m1 = topo_m4.ms["master1"] m2 = topo_m4.ms["master2"] TEST_ENTRY_NEW_PASS = '******'.format(TEST_ENTRY_NAME) log.info('Clean the error log') m2.deleteErrorLogs() log.info('Set replication loglevel') m2.config.loglevel((ErrorLog.REPLICA, )) log.info('Modifying entry {} - change userpassword on master 2'.format( TEST_ENTRY_DN)) test_user_m1 = UserAccount(topo_m4.ms["master1"], TEST_ENTRY_DN) test_user_m2 = UserAccount(topo_m4.ms["master2"], TEST_ENTRY_DN) test_user_m3 = UserAccount(topo_m4.ms["master3"], TEST_ENTRY_DN) test_user_m4 = UserAccount(topo_m4.ms["master4"], TEST_ENTRY_DN) test_user_m1.set('userpassword', TEST_ENTRY_NEW_PASS) log.info('Restart the servers to flush the logs') for num in range(1, 5): topo_m4.ms["master{}".format(num)].restart(timeout=10) m1_conn = test_user_m1.bind(TEST_ENTRY_NEW_PASS) m2_conn = test_user_m2.bind(TEST_ENTRY_NEW_PASS) m3_conn = test_user_m3.bind(TEST_ENTRY_NEW_PASS) m4_conn = test_user_m4.bind(TEST_ENTRY_NEW_PASS) log.info('Check the error log for the error with {}'.format(TEST_ENTRY_DN)) assert not m2.ds_error_log.match( '.*can.t add a change for uid={}.*'.format(TEST_ENTRY_NAME))
def test_conflict_attribute_single_valued(self, topology_m2, base_m2): """A RDN attribute being signle-valued, checks that after several operations MODRDN and MOD_REPL its RDN values are the same on both servers :id: c38ae613-5d1e-47cf-b051-c7284e64b817 :setup: Two supplier replication, test container for entries, enable plugin logging, audit log, error log for replica and access log for internal :steps: 1. Create a test entry uid=user_test_1000,... 2. Pause all replication agreements 3. On M1 rename it into employeenumber=foo1,... 4. On M2 rename it into employeenumber=foo2,... 5. On M1 MOD_REPL employeenumber:foo1 6. Resume all replication agreements 7. Check that entry on M1 has employeenumber=foo1 8. Check that entry on M2 has employeenumber=foo1 9. Check that entry on M1 and M2 has the same employeenumber values :expectedresults: 1. It should pass 2. It should pass 3. It should pass 4. It should pass 5. It should pass 6. It should pass 7. It should pass 8. It should pass 9. It should pass """ M1 = topology_m2.ms["supplier1"] M2 = topology_m2.ms["supplier2"] # add a test user with a dummy 'uid' extra value because modrdn removes # uid that conflict with 'account' objectclass test_users_m1 = UserAccounts(M1, base_m2.dn, rdn=None) user_1 = test_users_m1.create_test_user(uid=1000) user_1.add('objectclass', 'extensibleobject') user_1.add('uid', 'dummy') test_users_m2 = UserAccount(M2, user_1.dn) # Waiting fo the user to be replicated for i in range(0, 4): time.sleep(1) if test_users_m2.exists(): break assert (test_users_m2.exists()) # Stop replication agreements topology_m2.pause_all_replicas() # On M1 rename test entry in employeenumber=foo1 original_dn = user_1.dn user_1.rename('employeenumber=foo1') time.sleep(1) # On M2 rename test entry in employeenumber=foo2 M2.rename_s(original_dn, 'employeenumber=foo2') time.sleep(2) # on M1 MOD_REPL uid into foo1 user_1.replace('employeenumber', 'foo1') # resume replication agreements topology_m2.resume_all_replicas() time.sleep(5) # check that on M1, the entry 'employeenumber' has value 'foo1' final_dn = re.sub('^.*1000,', 'employeenumber=foo2,', original_dn) final_user_m1 = UserAccount(M1, final_dn) for val in final_user_m1.get_attr_vals_utf8('employeenumber'): log.info("Check %s is on M1" % val) assert (val in ['foo1']) # check that on M2, the entry 'employeenumber' has values 'foo1' final_user_m2 = UserAccount(M2, final_dn) for val in final_user_m2.get_attr_vals_utf8('employeenumber'): log.info("Check %s is on M2" % val) assert (val in ['foo1']) # check that the entry have the same uid values for val in final_user_m1.get_attr_vals_utf8('employeenumber'): log.info("Check M1.uid %s is also on M2" % val) assert (val in final_user_m2.get_attr_vals_utf8('employeenumber')) for val in final_user_m2.get_attr_vals_utf8('employeenumber'): log.info("Check M2.uid %s is also on M1" % val) assert (val in final_user_m1.get_attr_vals_utf8('employeenumber'))
def test_repl_agmt_bootstrap_credentials(topo): """Test that the agreement bootstrap credentials works if the default credentials fail for some reason. :id: 38c8095c-d958-415a-b602-74854b7882b3 :customerscenario: True :setup: 2 Master Instances :steps: 1. Change the bind dn group member passwords 2. Verify replication is not working 3. Create a new repl manager on master 2 for bootstrapping 4. Add bootstrap credentials to agmt on master 1 5. Verify replication is now working with bootstrap creds 6. Trigger new repl session and default credentials are used first :expectedresults: 1. Success 2. Success 3. Success 4. Success 5. Success 6. Success """ # Gather all of our objects for the test m1 = topo.ms["master1"] m2 = topo.ms["master2"] master1_replica = Replicas(m1).get(DEFAULT_SUFFIX) master2_replica = Replicas(m2).get(DEFAULT_SUFFIX) master2_users = UserAccounts(m2, DEFAULT_SUFFIX) m1_agmt = master1_replica.get_agreements().list()[0] num_of_original_users = len(master2_users.list()) # Change the member's passwords which should break replication bind_group = Group(m2, dn=BIND_GROUP_DN) members = bind_group.list_members() for member_dn in members: member = UserAccount(m2, dn=member_dn) member.replace('userPassword', 'not_right') time.sleep(3) m1_agmt.pause() m1_agmt.resume() # Verify replication is not working, a new user should not be replicated users = UserAccounts(m1, DEFAULT_SUFFIX) test_user = users.ensure_state(properties=TEST_USER_PROPERTIES) time.sleep(3) assert len(master2_users.list()) == num_of_original_users # Create a repl manager on replica repl_mgr = BootstrapReplicationManager(m2, dn=BOOTSTRAP_MGR_DN) mgr_properties = { 'uid': 'replication manager', 'cn': 'replication manager', 'userPassword': BOOTSTRAP_MGR_PWD, } repl_mgr.create(properties=mgr_properties) # Update master 2 config master2_replica.remove_all('nsDS5ReplicaBindDNGroup') master2_replica.remove_all('nsDS5ReplicaBindDnGroupCheckInterval') master2_replica.replace('nsDS5ReplicaBindDN', BOOTSTRAP_MGR_DN) # Add bootstrap credentials to master1 agmt, and restart agmt m1_agmt.replace('nsds5ReplicaBootstrapTransportInfo', 'LDAP') m1_agmt.replace('nsds5ReplicaBootstrapBindMethod', 'SIMPLE') m1_agmt.replace('nsds5ReplicaBootstrapCredentials', BOOTSTRAP_MGR_PWD) m1_agmt.replace('nsds5ReplicaBootstrapBindDN', BOOTSTRAP_MGR_DN) m1_agmt.pause() m1_agmt.resume() # Verify replication is working. The user should have been replicated time.sleep(3) assert len(master2_users.list()) > num_of_original_users # Finally check if the default credentials are used on the next repl # session. Clear out the logs, and disable log buffering. Then # trigger a replication update/session. m1_agmt.pause() m2.stop() m2.deleteLog(m2.accesslog) # Clear out the logs m2.start() m2.config.set('nsslapd-accesslog-logbuffering', 'off') m1_agmt.resume() test_user.delete() time.sleep(3) # We know if the default credentials are used it will fail (err=49) results = m2.ds_access_log.match('.* err=49 .*') assert len(results) > 0
def test_undefined_in_group_eval_fourteen(topo, test_user, aci_of_user): """ Test with parent keyword that Yields FALSE as description is not present in tested entry :id: 5c527218-7841-11e8-8909-8c16451d917b :setup: server :steps: 1. Add test entry 2. Take a count of users using DN_DM 3. Add test user 4. add aci 5. test should fullfil the aci rules :expectedresults: 1. Entry should be added 2. Operation should succeed 3. Operation should succeed 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";)' ) user = UserAccount(topo.standalone, GROUPDNATTRSCRATCHENTRY_GLOBAL) user.add("description", [ALLGROUPS_GLOBAL, GROUPG_GLOBAL]) conn = UserAccount(topo.standalone, DEEPUSER2_GLOBAL).bind(PW_DM) # Test with parent keyword user1 = UserAccount(conn, GROUPDNATTRCHILDSCRATCHENTRY_GLOBAL) with pytest.raises(ldap.INSUFFICIENT_ACCESS): user1.add("sn", "Fred") assert UserAccount(conn, DEEPGROUPSCRATCHENTRY_GLOBAL).get_attr_val_utf8('cn') user.remove("description", [ALLGROUPS_GLOBAL, GROUPG_GLOBAL])
def test_deny_all_access_with_targetfilter_using_boolean_or_of_two_equality_search( topo, test_uer, aci_of_user, request ): """Search Test 18 Deny all access with targetfilter using boolean OR of two equality search :id: 29cc35fa-793f-11e8-988f-8c16451d917b :setup: Standalone Instance :steps: 1. Add Entry 2. Add ACI 3. Bind with test USER_ANUJ 4. Try search 5. Delete Entry,test USER_ANUJ, ACI :expectedresults: 1. Operation should success 2. Operation should success 3. Operation should success 4. Operation should Fail 5. Operation should success """ Domain(topo.standalone, DEFAULT_SUFFIX).add("aci",'(target = ldap:///{})(targetattr = "*")' '(targetfilter = (|(cn=scarter)(cn=jvaughan)))(version 3.0; acl "{}"; ' 'deny absolute (all) (userdn = "ldap:///anyone") ;)'.format(DEFAULT_SUFFIX, request.node.name)) UserAccount(topo.standalone, USER_ANANDA).set("cn", "scarter") UserAccount(topo.standalone, USER_ANUJ).set("cn", "jvaughan") conn = UserAccount(topo.standalone, USER_ANANDA).bind(PW_DM) # aci will deny_all_access_with_targetfilter_using_boolean_or_of_two_equality_search user = UserAccount(conn, USER_ANANDA) with pytest.raises(IndexError): user.get_attr_val_utf8('uid') # aci will deny_all_access_with_targetfilter_using_boolean_or_of_two_equality_search user = UserAccount(conn, USER_ANUJ) with pytest.raises(IndexError): user.get_attr_val_utf8('uid') # with root no blockage assert UserAccount(topo.standalone, USER_ANANDA).get_attr_val_utf8('uid') == 'Ananda Borah' # with root no blockage assert UserAccount(topo.standalone, USER_ANUJ).get_attr_val_utf8('uid') == 'Anuj Borah'
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 _add_user(request, topo): org = Organization(topo.standalone).create(properties={"o": "acivattr"}, basedn=DEFAULT_SUFFIX) org.add('aci', '(targetattr="*")(targetfilter="(nsrole=*)")(version 3.0; aci "tester"; ' 'allow(all) userdn="ldap:///cn=enguser1,ou=eng,o=acivattr,{}";)'.format(DEFAULT_SUFFIX)) ou = OrganizationalUnit(topo.standalone, "ou=eng,o=acivattr,{}".format(DEFAULT_SUFFIX)) ou.create(properties={'ou': 'eng'}) ou = OrganizationalUnit(topo.standalone, "ou=sales,o=acivattr,{}".format(DEFAULT_SUFFIX)) ou.create(properties={'ou': 'sales'}) roles = FilterRoles(topo.standalone, DNBASE) roles.create(properties={'cn':'FILTERROLEENGROLE', 'nsRoleFilter':'cn=eng*'}) roles.create(properties={'cn': 'FILTERROLESALESROLE', 'nsRoleFilter': 'cn=sales*'}) nsContainer(topo.standalone, 'cn=cosClassicGenerateEmployeeTypeUsingnsroleTemplates,o=acivattr,{}'.format(DEFAULT_SUFFIX)).create( properties={'cn': 'cosTemplates'}) properties = {'employeeType': 'EngType', 'cn':'"cn=filterRoleEngRole,o=acivattr,dc=example,dc=com",cn=cosClassicGenerateEmployeeTypeUsingnsroleTemplates,o=acivattr,dc=example,dc=com'} CosTemplate(topo.standalone,'cn="cn=filterRoleEngRole,o=acivattr,dc=example,dc=com",' 'cn=cosClassicGenerateEmployeeTypeUsingnsroleTemplates,o=acivattr,{}'.format(DEFAULT_SUFFIX)).\ create(properties=properties) properties = {'employeeType': 'SalesType', 'cn': '"cn=filterRoleSalesRole,o=acivattr,dc=example,dc=com",cn=cosClassicGenerateEmployeeTypeUsingnsroleTemplates,o=acivattr,dc=example,dc=com'} CosTemplate(topo.standalone, 'cn="cn=filterRoleSalesRole,o=acivattr,dc=example,dc=com",cn=cosClassicGenerateEmployeeTypeUsingnsroleTemplates,' 'o=acivattr,{}'.format(DEFAULT_SUFFIX)).create(properties=properties) properties = { 'cosTemplateDn': 'cn=cosClassicGenerateEmployeeTypeUsingnsroleTemplates,o=acivattr,{}'.format(DEFAULT_SUFFIX), 'cosAttribute': 'employeeType', 'cosSpecifier': 'nsrole', 'cn': 'cosClassicGenerateEmployeeTypeUsingnsrole'} CosClassicDefinition(topo.standalone, 'cn=cosClassicGenerateEmployeeTypeUsingnsrole,o=acivattr,{}'.format(DEFAULT_SUFFIX)).create( properties=properties) properties = { 'uid': 'salesuser1', 'cn': 'salesuser1', 'sn': 'user', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + 'salesuser1', 'userPassword': PW_DM } user = UserAccount(topo.standalone, 'cn=salesuser1,ou=sales,o=acivattr,{}'.format(DEFAULT_SUFFIX)) user.create(properties=properties) properties = { 'uid': 'salesmanager1', 'cn': 'salesmanager1', 'sn': 'user', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + 'salesmanager1', 'userPassword': PW_DM, } user = UserAccount(topo.standalone, 'cn=salesmanager1,ou=sales,o=acivattr,{}'.format(DEFAULT_SUFFIX)) user.create(properties=properties) properties = { 'uid': 'enguser1', 'cn': 'enguser1', 'sn': 'user', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + 'enguser1', 'userPassword': PW_DM } user = UserAccount(topo.standalone, 'cn=enguser1,ou=eng,o=acivattr,{}'.format(DEFAULT_SUFFIX)) user.create(properties=properties) properties = { 'uid': 'engmanager1', 'cn': 'engmanager1', 'sn': 'user', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + 'engmanager1', 'userPassword': PW_DM } user = UserAccount(topo.standalone, 'cn=engmanager1,ou=eng,o=acivattr,{}'.format(DEFAULT_SUFFIX)) user.create(properties=properties) def fin(): for DN in [ENG_USER,SALES_UESER,ENG_MANAGER,SALES_MANAGER,FILTERROLESALESROLE,FILTERROLEENGROLE,ENG_OU,SALES_OU, 'cn="cn=filterRoleEngRole,o=acivattr,dc=example,dc=com",' 'cn=cosClassicGenerateEmployeeTypeUsingnsroleTemplates,o=acivattr,dc=example,dc=com', 'cn="cn=filterRoleSalesRole,o=acivattr,dc=example,dc=com",' 'cn=cosClassicGenerateEmployeeTypeUsingnsroleTemplates,o=acivattr,{}'.format(DEFAULT_SUFFIX), 'cn=cosClassicGenerateEmployeeTypeUsingnsroleTemplates,o=acivattr,{}'.format(DEFAULT_SUFFIX), 'cn=cosClassicGenerateEmployeeTypeUsingnsrole,o=acivattr,{}'.format(DEFAULT_SUFFIX), DNBASE]: UserAccount(topo.standalone, DN).delete() request.addfinalizer(fin)
def test_allow_write_access_to_userdnattr(topo, aci_of_user, cleanup_tree, request): """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 "{}";allow (write) (userdn = "ldap:///anyone"); )'.format( DEFAULT_SUFFIX, request.node.name) 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_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_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_replica_backup_and_restore(topo_m4): """Test Backup and restore :id: 5ad1b85c-e765-11e8-9668-8c16451d917b :setup: standalone :steps: 1. Add entries 2. Take backup db2ldif on supplier1 3. Delete entries on supplier1 4. Restore entries ldif2db 5. Check entries :expected results: 1. Should success 2. Should success 3. Should success 4. Should success 5. Should success """ # Testing bug #830335: Taking a replica backup and Restore on M1 after deleting few entries from M1 nad M2 # Make sure to update S1 to avoid useless replication delay repl = ReplicationManager(DEFAULT_SUFFIX) users = UserAccounts(topo_m4.ms["supplier1"], DEFAULT_SUFFIX) for i in range(20, 25): users.create_test_user(uid=i) time.sleep(1) repl.wait_for_replication(topo_m4.ms["supplier1"], topo_m4.ms["supplier2"]) repl.test_replication(topo_m4.ms["supplier1"], topo_m4.ms["supplier2"], 30) # Get a backup topo_m4.ms["supplier1"].stop() topo_m4.ms["supplier1"].db2ldif( bename=DEFAULT_BENAME, suffixes=[DEFAULT_SUFFIX], excludeSuffixes=[], encrypt=False, repl_data=True, outputfile="/tmp/output_file", ) # Do some updates (that are not in the backup # and restore the backup topo_m4.ms["supplier1"].start() for i in users.list(): topo_m4.ms["supplier1"].delete_s(i.dn) repl.wait_for_replication(topo_m4.ms["supplier1"], topo_m4.ms["supplier2"]) repl.test_replication(topo_m4.ms["supplier1"], topo_m4.ms["supplier2"], 30) # disable the agmt (while server is up) to avoid the DEL get replayed too early for agmt in list_agmt_towards(topo_m4, "supplier1"): agmt.pause() topo_m4.ms["supplier1"].stop() topo_m4.ms["supplier1"].ldif2db( bename=None, excludeSuffixes=None, encrypt=False, suffixes=[DEFAULT_SUFFIX], import_file="/tmp/output_file", ) topo_m4.ms["supplier1"].start() # Check that the updates (DEL) are no longer there for i in users.list(): testuser = UserAccount(topo_m4.ms["supplier1"], i.dn) assert testuser.exists() # Re enable the agmts for agmt in list_agmt_towards(topo_m4, "supplier1"): agmt.resume() # Here the changelog of supplier1 has been cleared. # Let's wait the supplier2 resync supplier1 BEFORE doing # any update to supplier1. # Else (a new update on S1), the others supplier will not update # it and the changelog of S1 will not contain the starting points # of the others suppliers. repl.wait_for_replication(topo_m4.ms["supplier2"], topo_m4.ms["supplier1"]) repl.wait_for_replication(topo_m4.ms["supplier3"], topo_m4.ms["supplier1"]) repl.wait_for_replication(topo_m4.ms["supplier4"], topo_m4.ms["supplier1"]) for i in range(31, 35): users.create_test_user(uid=i) time.sleep(1) repl.wait_for_replication(topo_m4.ms["supplier1"], topo_m4.ms["supplier2"]) repl.test_replication(topo_m4.ms["supplier1"], topo_m4.ms["supplier2"], 30)
def test_targattrfilters_keyword(topo): """ 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: 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 = Domain(topo.standalone, DEFAULT_SUFFIX) domain.set('aci', None) ou = OrganizationalUnit(topo.standalone, 'ou=bug979515,{}'.format(DEFAULT_SUFFIX)) ou.create(properties={'ou': 'bug979515'}) Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", '(target="ldap:///ou=bug979515,{}") ' '(targetattr= "uid") ( version 3.0; acl "read other subscriber"; allow (compare, read, search) ' 'userdn="ldap:///uid=*,ou=bug979515,{}" ; )'.format(DEFAULT_SUFFIX, DEFAULT_SUFFIX)) properties = { 'uid': 'acientryusr1', 'cn': 'acientryusr1', 'sn': 'user', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + 'acientryusr1' } user = UserAccount(topo.standalone, 'cn=acientryusr1,ou=bug979515,{}'.format(DEFAULT_SUFFIX)) user.create(properties=properties) user.set('telephoneNumber', '99972566596') user.set('mail', '*****@*****.**') user.set("userPassword", "password") properties = { 'uid': 'newaciphoneusr1', 'cn': 'newaciphoneusr1', 'sn': 'user', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + 'newaciphoneusr1' } user = UserAccount(topo.standalone, 'cn=newaciphoneusr1,ou=bug979515,{}'.format(DEFAULT_SUFFIX)) user.create(properties=properties) user.set('telephoneNumber', '99972566596') user.set('mail', '*****@*****.**') conn = UserAccount(topo.standalone, "cn=acientryusr1,ou=bug979515,{}".format(DEFAULT_SUFFIX)).bind(PW_DM) # Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted)) user = UserAccount(conn, "cn=acientryusr1,ou=bug979515,{}".format(DEFAULT_SUFFIX)) with pytest.raises(IndexError): user.get_attr_vals('mail') user.get_attr_vals('telephoneNumber') user.get_attr_vals('cn') user = UserAccount(topo.standalone, "cn=acientryusr1,ou=bug979515,{}".format(DEFAULT_SUFFIX)) user.get_attr_vals('mail') user.get_attr_vals('telephoneNumber') user.get_attr_vals('cn')
def test_gecos_directoryString_wins_M2(topo_m2, request): """Check that if inital syntax are IA5(M2) and DirectoryString(M1) Then directoryString wins when nsSchemaCSN M2 is the greatest :id: 2da7f1b1-f86d-4072-a940-ba56d4bc8348 :setup: Two suppliers replication setup :steps: 1. Create a testuser on M1 2 Stop M1 and M2 3 Change gecos def on M2 to be IA5 4 Start M1 and M2 5 Update M2 schema so that M2 has greatest nsSchemaCSN 6 Update testuser on M2 and trigger replication to M1 7 Update testuser on M2 with gecos directoryString value 8 Check replication is still working 9 Check gecos is DirectoryString on M1 and M2 :expectedresults: 1. success 2. success 3. success 4. success 5. success 6. success 7. success 8. success 9. success """ repl = ReplicationManager(DEFAULT_SUFFIX) m1 = topo_m2.ms["supplier1"] m2 = topo_m2.ms["supplier2"] # create a test user testuser_dn = 'uid={},{}'.format('testuser', DEFAULT_SUFFIX) testuser = UserAccount(m1, testuser_dn) try: testuser.create( properties={ 'uid': 'testuser', 'cn': 'testuser', 'sn': 'testuser', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/testuser', }) except ldap.ALREADY_EXISTS: pass testuser.replace('displayName', 'to trigger replication M1-> M2') repl.wait_for_replication(m1, m2) # Stop suppliers to update the schema m1.stop() m2.stop() # on M1: gecos is DirectoryString (default) # on M2: gecos is IA5 schema_filename = (m2.schemadir + "/99user.ldif") try: with open(schema_filename, 'w') as schema_file: schema_file.write("dn: cn=schema\n") schema_file.write( "attributetypes: ( 1.3.6.1.1.1.1.2 NAME " + "'gecos' DESC 'The GECOS field; the common name' " + "EQUALITY caseIgnoreIA5Match " + "SUBSTR caseIgnoreIA5SubstringsMatch " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 " + "SINGLE-VALUE )\n") os.chmod(schema_filename, 0o777) except OSError as e: log.fatal("Failed to update schema file: " + "{} Error: {}".format(schema_filename, str(e))) # start the instances m1.start() m2.start() # Check that gecos is IA5 on M2 schema = SchemaLegacy(m2) attributetypes = schema.query_attributetype('gecos') assert attributetypes[0].syntax == "1.3.6.1.4.1.1466.115.121.1.26" # update M2 schema to increase its nsschemaCSN new_at = "( dummy-oid NAME 'dummy' DESC 'dummy attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'RFC 2307' )" m2.schema.add_schema('attributetypes', ensure_bytes(new_at)) # update just to trigger replication M2->M1 # and update of M2 schema testuser_m2 = UserAccount(m2, testuser_dn) testuser_m2.replace('displayName', 'to trigger replication M2-> M1') # Add a gecos UTF value on M1 testuser.replace('gecos', 'Hélène') # Check replication is still working testuser.replace('displayName', 'ascii value') repl.wait_for_replication(m1, m2) assert testuser_m2.exists() assert testuser_m2.get_attr_val_utf8('displayName') == 'ascii value' # Check that gecos is DirectoryString on M1 schema = SchemaLegacy(m1) attributetypes = schema.query_attributetype('gecos') assert attributetypes[0].syntax == "1.3.6.1.4.1.1466.115.121.1.15" # Check that gecos is DirectoryString on M2 schema = SchemaLegacy(m2) attributetypes = schema.query_attributetype('gecos') assert attributetypes[0].syntax == "1.3.6.1.4.1.1466.115.121.1.15" def fin(): m1.start() m2.start() testuser.delete() m1.schema.del_schema('attributetypes', ensure_bytes(new_at)) repl.wait_for_replication(m1, m2) # on M2 restore a default 99user.ldif m2.stop() os.remove(m2.schemadir + "/99user.ldif") schema_filename = (m2.schemadir + "/99user.ldif") try: with open(schema_filename, 'w') as schema_file: schema_file.write("dn: cn=schema\n") os.chmod(schema_filename, 0o777) except OSError as e: log.fatal("Failed to update schema file: " + "{} Error: {}".format(schema_filename, str(e))) m2.start() request.addfinalizer(fin)
def __init__(self, topo, value, conn): self.topo = topo self.value = value self.conn = conn self.user = UserAccount(self.conn, USER_DELADD)
def test_undefined_in_group_eval_eleven(topo, test_user, aci_of_user): """ Aci will not allow access as description is there with the user entry which is not allowed in ACI :id: 4cfa28e2-7841-11e8-8117-8c16451d917b :setup: server :steps: 1. Add test entry 2. Take a count of users using DN_DM 3. Add test user 4. add aci 5. test should fullfil the aci rules :expectedresults: 1. Entry should be added 2. Operation should succeed 3. Operation should succeed 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");)' ) user = UserAccount(topo.standalone, DEEPGROUPSCRATCHENTRY_GLOBAL) user.add("description", [ALLGROUPS_GLOBAL, GROUPH_GLOBAL]) conn = UserAccount(topo.standalone, DEEPUSER_GLOBAL).bind(PW_DM) # Test that not(UNDEFINED(attrval1)) user1 = UserAccount(conn, DEEPGROUPSCRATCHENTRY_GLOBAL) with pytest.raises(ldap.INSUFFICIENT_ACCESS): user1.add("sn", "Fred1") assert user.get_attr_val_utf8('cn') user.remove("description", [ALLGROUPS_GLOBAL, GROUPH_GLOBAL])
def delete(self): UserAccount(self.conn, USER_DELADD).remove("title", None)
def test_pwd_reset(topology_st, test_user): """Test new password policy attribute "pwdReset" :id: 03db357b-4800-411e-a36e-28a534293004 :customerscenario: True :setup: Standalone instance :steps: 1. Enable passwordMustChange 2. Reset user's password 3. Check that the pwdReset attribute is set to TRUE 4. Bind as the user and change its password 5. Check that pwdReset is now set to FALSE 6. Reset password policy configuration :expected results: 1. Success 2. Success 3. Success 4. Success 5. Success 6. Success """ # Set password policy config topology_st.standalone.config.replace('passwordMustChange', 'on') time.sleep(.5) # 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' # 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) assert our_user.get_attr_val_utf8('pwdReset') == 'FALSE' # Reset password policy config topology_st.standalone.config.replace('passwordMustChange', 'off') # Reset user's password our_user.replace('userpassword', TEST_USER_PWD)
def __init__(self, topo, value): self.topo = topo self.value = value self.user = UserAccount(self.topo.standalone, USER_DELADD)
def test_conflict_attribute_multi_valued(self, topology_m2, base_m2): """A RDN attribute being multi-valued, checks that after several operations MODRDN and MOD_REPL its RDN values are the same on both servers :id: 225b3522-8ed7-4256-96f9-5fab9b7044a5 :setup: Two supplier replication, audit log, error log for replica and access log for internal :steps: 1. Create a test entry uid=user_test_1000,... 2. Pause all replication agreements 3. On M1 rename it into uid=foo1,... 4. On M2 rename it into uid=foo2,... 5. On M1 MOD_REPL uid:foo1 6. Resume all replication agreements 7. Check that entry on M1 has uid=foo1, foo2 8. Check that entry on M2 has uid=foo1, foo2 9. Check that entry on M1 and M2 has the same uid values :expectedresults: 1. It should pass 2. It should pass 3. It should pass 4. It should pass 5. It should pass 6. It should pass 7. It should pass 8. It should pass 9. It should pass """ M1 = topology_m2.ms["supplier1"] M2 = topology_m2.ms["supplier2"] # add a test user test_users_m1 = UserAccounts(M1, base_m2.dn, rdn=None) user_1 = test_users_m1.create_test_user(uid=1000) test_users_m2 = UserAccount(M2, user_1.dn) # Waiting fo the user to be replicated for i in range(0, 4): time.sleep(1) if test_users_m2.exists(): break assert (test_users_m2.exists()) # Stop replication agreements topology_m2.pause_all_replicas() # On M1 rename test entry in uid=foo1 original_dn = user_1.dn user_1.rename('uid=foo1') time.sleep(1) # On M2 rename test entry in uid=foo2 M2.rename_s(original_dn, 'uid=foo2') time.sleep(2) # on M1 MOD_REPL uid into foo1 user_1.replace('uid', 'foo1') # resume replication agreements topology_m2.resume_all_replicas() time.sleep(5) # check that on M1, the entry 'uid' has two values 'foo1' and 'foo2' final_dn = re.sub('^.*1000,', 'uid=foo2,', original_dn) final_user_m1 = UserAccount(M1, final_dn) for val in final_user_m1.get_attr_vals_utf8('uid'): log.info("Check %s is on M1" % val) assert (val in ['foo1', 'foo2']) # check that on M2, the entry 'uid' has two values 'foo1' and 'foo2' final_user_m2 = UserAccount(M2, final_dn) for val in final_user_m2.get_attr_vals_utf8('uid'): log.info("Check %s is on M1" % val) assert (val in ['foo1', 'foo2']) # check that the entry have the same uid values for val in final_user_m1.get_attr_vals_utf8('uid'): log.info("Check M1.uid %s is also on M2" % val) assert (val in final_user_m2.get_attr_vals_utf8('uid')) for val in final_user_m2.get_attr_vals_utf8('uid'): log.info("Check M2.uid %s is also on M1" % val) assert (val in final_user_m1.get_attr_vals_utf8('uid'))
def _add_user(request, topo): for i in ["Product Development", 'Accounting', "Human Resources"]: ou = OrganizationalUnit(topo.standalone, "ou={},{}".format(i, DEFAULT_SUFFIX)) ou.create(properties={'ou': i}) properties = { 'uid': 'Jeff Vedder', 'cn': 'Jeff Vedder', 'sn': 'user', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + 'JeffVedder', 'userPassword': '******' } user = UserAccount(topo.standalone, 'cn=Jeff Vedder,{}'.format(CONTAINER_1_DELADD)) user.create(properties=properties) user.set('secretary', 'cn=Arpitoo Borah, o=Red Hat, c=As') user.set('mail', '*****@*****.**') properties = { 'uid': 'Sam Carter', 'cn': 'Sam Carter', 'sn': 'user', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + 'SamCarter', 'userPassword': '******' } user = UserAccount(topo.standalone, 'cn=Sam Carter,{}'.format(CONTAINER_2_DELADD)) user.create(properties=properties) properties = { 'uid': 'Kirsten Vaughan', 'cn': 'Kirsten Vaughan', 'sn': 'Kirsten Vaughan', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + 'KirstenVaughan', 'userPassword': '******' } user = UserAccount( topo.standalone, 'cn=Kirsten Vaughan, ou=Human Resources,{}'.format(DEFAULT_SUFFIX)) user.create(properties=properties) properties = { 'uid': 'HARRY', 'cn': 'HARRY', 'sn': 'HARRY', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + 'HARRY', 'userPassword': '******' } user = UserAccount(topo.standalone, 'cn=HARRY, ou=Accounting,{}'.format(DEFAULT_SUFFIX)) user.create(properties=properties) def fin(): for DN in [ USER_DELADD, USER_WITH_ACI_DELADD, FRED, HARRY, KIRSTENVAUGHAN, HUMAN_OU_GLOBAL, CONTAINER_2_DELADD, CONTAINER_1_DELADD ]: ua = UserAccount(topo.standalone, DN) try: ua.delete() except: pass request.addfinalizer(fin)
def test_fast_slow_import(topo, _toggle_private_import_mem, _import_clean): """With nsslapd-db-private-import-mem: on is faster import. :id: 3044331c-9c0e-11ea-ac9f-8c16451d917b :setup: Standalone Instance :steps: 1. Let's set nsslapd-db-private-import-mem:on, nsslapd-import-cache-autosize: 0 2. Measure offline import time duration total_time1 3. Now nsslapd-db-private-import-mem:off 4. Measure offline import time duration total_time2 5. total_time1 < total_time2 6. Set nsslapd-db-private-import-mem:on, nsslapd-import-cache-autosize: -1 7. Measure offline import time duration total_time1 8. Now nsslapd-db-private-import-mem:off 9. Measure offline import time duration total_time2 10. total_time1 < total_time2 :expected results: 1. Operation successful 2. Operation successful 3. Operation successful 4. Operation successful 5. Operation successful 6. Operation successful 7. Operation successful 8. Operation successful 9. Operation successful 10. Operation successful """ # Let's set nsslapd-db-private-import-mem:on, nsslapd-import-cache-autosize: 0 config = LDBMConfig(topo.standalone) # Measure offline import time duration total_time1 total_time1 = _import_offline(topo, 1000) # Now nsslapd-db-private-import-mem:off config.replace('nsslapd-db-private-import-mem', 'off') accounts = Accounts(topo.standalone, DEFAULT_SUFFIX) for i in accounts.filter('(uid=*)'): UserAccount(topo.standalone, i.dn).delete() # Measure offline import time duration total_time2 total_time2 = _import_offline(topo, 1000) # total_time1 < total_time2 log.info("total_time1 = %f" % total_time1) log.info("total_time2 = %f" % total_time2) assert total_time1 < total_time2 # Set nsslapd-db-private-import-mem:on, nsslapd-import-cache-autosize: -1 config.replace_many( ('nsslapd-db-private-import-mem', 'on'), ('nsslapd-import-cache-autosize', '-1')) for i in accounts.filter('(uid=*)'): UserAccount(topo.standalone, i.dn).delete() # Measure offline import time duration total_time1 total_time1 = _import_offline(topo, 1000) # Now nsslapd-db-private-import-mem:off config.replace('nsslapd-db-private-import-mem', 'off') for i in accounts.filter('(uid=*)'): UserAccount(topo.standalone, i.dn).delete() # Measure offline import time duration total_time2 total_time2 = _import_offline(topo, 1000) # total_time1 < total_time2 log.info("toral_time1 = %f" % total_time1) log.info("total_time2 = %f" % total_time2) assert total_time1 < total_time2
def _add_user(request, topo): """ A Function that will create necessary users delete the created user """ ous = OrganizationalUnits(topo.standalone, DEFAULT_SUFFIX) ou_ou = ous.create(properties={'ou': 'roledntest'}) ou_ou.set('aci', [ f'(target="ldap:///{NESTED_ROLE_TESTER}")(targetattr="*") ' f'(version 3.0; aci "nested role aci"; allow(all)' f'roledn = "ldap:///{ROLE2}";)', 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'(version 3.0; aci "anyone role aci"; allow(all) ' f'roledn = "ldap:///anyone";)', f'(target="ldap:///{NOT_RULE_ACCESS}")(targetattr=*)' f'(version 3.0; aci "not role aci"; allow(all)' f'roledn != "ldap:///{ROLE1} || ldap:///{ROLE21}";)' ]) nestedroles = NestedRoles(topo.standalone, OU_ROLE) for i in [('role2', [ROLE1, ROLE21]), ('role3', [ROLE2, ROLE31])]: nestedroles.create(properties={'cn': i[0], 'nsRoleDN': i[1]}) managedroles = ManagedRoles(topo.standalone, OU_ROLE) for i in ['ROLE1', 'ROLE21', 'ROLE31']: managedroles.create(properties={'cn': i}) filterroles = FilterRoles(topo.standalone, OU_ROLE) filterroles.create( properties={ 'cn': 'filterRole', 'nsRoleFilter': 'sn=Dr Drake', 'description': 'filter role tester' }) users = UserAccounts(topo.standalone, OU_ROLE, rdn=None) for i in [('STEVE_ROLE', ROLE1, 'Has roles 1, 2 and 3.'), ('HARRY_ROLE', ROLE21, 'Has roles 21, 2 and 3.'), ('MARY_ROLE', ROLE31, 'Has roles 31 and 3.')]: users.create( properties={ 'uid': i[0], 'cn': i[0], 'sn': 'user', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + i[0], 'userPassword': PW_DM, 'nsRoleDN': i[1], 'Description': i[2] }) for i in [('JOE_ROLE', 'Has filterRole.'), ('NOROLEUSER', 'Has no roles.'), ('SCRACHENTRY', 'Entry to test rights on.'), ('all access', 'Everyone has acccess (incl anon).'), ('not rule access', 'Only accessible to mary.'), ('or rule access', 'Only to steve and harry but nbot mary or anon'), ('nested role tester', 'Only accessible to harry and steve.')]: users.create( properties={ 'uid': i[0], 'cn': i[0], 'sn': 'user', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + i[0], 'userPassword': PW_DM, 'Description': i[1] }) # Setting SN for user JOE UserAccount(topo.standalone, f'uid=JOE_ROLE,ou=roledntest,{DEFAULT_SUFFIX}').set( 'sn', 'Dr Drake') def fin(): """ It will delete the created users """ for i in users.list() + managedroles.list() + nestedroles.list(): i.delete() request.addfinalizer(fin)
def test_basic_with_hub(topo): """Check that basic operations work in cascading replication, this includes testing plugins that perform internal operatons, and replicated password policy state attributes. :id: 4ac85552-45bc-477b-89a4-226dfff8c6cc :setup: 1 master, 1 hub, 1 consumer :steps: 1. Enable memberOf plugin and set password account lockout settings 2. Restart the instance 3. Add a user 4. Add a group 5. Test that the replication works 6. Add the user as a member to the group 7. Test that the replication works 8. Issue bad binds to update passwordRetryCount 9. Test that replicaton works 10. Check that passwordRetyCount was replicated :expectedresults: 1. Should be a success 2. Should be a success 3. Should be a success 4. Should be a success 5. Should be a success 6. Should be a success 7. Should be a success 8. Should be a success 9. Should be a success 10. Should be a success """ repl_manager = ReplicationManager(DEFAULT_SUFFIX) master = topo.ms["master1"] consumer = topo.cs["consumer1"] hub = topo.hs["hub1"] for inst in topo: config_memberof(inst) inst.config.set('passwordlockout', 'on') inst.config.set('passwordlockoutduration', '60') inst.config.set('passwordmaxfailure', '3') inst.config.set('passwordIsGlobalPolicy', 'on') # Create user user1 = UserAccount(master, BIND_DN) user_props = TEST_USER_PROPERTIES.copy() user_props.update({ 'sn': BIND_RDN, 'cn': BIND_RDN, 'uid': BIND_RDN, 'inetUserStatus': '1', 'objectclass': 'extensibleObject', 'userpassword': PASSWORD }) user1.create(properties=user_props, basedn=SUFFIX) # Create group groups = Groups(master, DEFAULT_SUFFIX) group = groups.create(properties={'cn': 'group'}) # Test replication repl_manager.test_replication(master, consumer) # Trigger memberOf plugin by adding user to group group.replace('member', user1.dn) # Test replication once more repl_manager.test_replication(master, consumer) # Issue bad password to update passwordRetryCount try: master.simple_bind_s(user1.dn, "badpassword") except: pass # Test replication one last time master.simple_bind_s(DN_DM, PASSWORD) repl_manager.test_replication(master, consumer) # Finally check if passwordRetyCount was replicated to the hub and consumer user1 = UserAccount(hub, BIND_DN) count = user1.get_attr_val_int('passwordRetryCount') if count is None: log.fatal('PasswordRetyCount was not replicated to hub') assert False if int(count) != 1: log.fatal('PasswordRetyCount has unexpected value: {}'.format(count)) assert False user1 = UserAccount(consumer, BIND_DN) count = user1.get_attr_val_int('passwordRetryCount') if count is None: log.fatal('PasswordRetyCount was not replicated to consumer') assert False if int(count) != 1: log.fatal('PasswordRetyCount has unexpected value: {}'.format(count)) assert False
def test_multiple_scopes(topo): """Specify memberOf works when multiple include scopes are defined :id: fbcd70cc-c83d-4c79-bd5b-2d8f017545ae :setup: Standalone Instance :steps: 1. Set multiple include scopes 2. Test members added to both scopes are correctly updated 3. Test user outside of scope was not updated 4. Set exclude scope 5. Move user into excluded subtree and check the membership is correct :expectedresults: 1. Success 2. Success 3. Success 4. Success 5. Success """ inst = topo.standalone # configure plugin memberof = MemberOfPlugin(inst) memberof.enable() memberof.add('memberOfEntryScope', SUBTREE_1) memberof.add('memberOfEntryScope', SUBTREE_2) inst.restart() # Add setup entries add_container(inst, SUFFIX, 'sub1') add_container(inst, SUFFIX, 'sub2') add_container(inst, SUFFIX, 'sub3') add_member_and_group(inst, 'm1', 'g1', SUBTREE_1) add_member_and_group(inst, 'm2', 'g2', SUBTREE_2) add_member_and_group(inst, 'm3', 'g3', SUBTREE_3) # Check users 1 and 2 were correctly updated check_membership(inst, f'uid=test_m1,{SUBTREE_1}', f'cn=g1,{SUBTREE_1}', True) check_membership(inst, f'uid=test_m2,{SUBTREE_2}', f'cn=g2,{SUBTREE_2}', True) # Check that user3, which is out of scope, was not updated check_membership(inst, f'uid=test_m3,{SUBTREE_3}', f'cn=g1,{SUBTREE_1}', False) check_membership(inst, f'uid=test_m3,{SUBTREE_3}', f'cn=g2,{SUBTREE_2}', False) check_membership(inst, f'uid=test_m3,{SUBTREE_3}', f'cn=g3,{SUBTREE_3}', False) # Set exclude scope EXCLUDED_SUBTREE = 'cn=exclude,%s' % SUFFIX EXCLUDED_USER = f"uid=test_m1,{EXCLUDED_SUBTREE}" INCLUDED_USER = f"uid=test_m1,{SUBTREE_1}" GROUP_DN = f'cn=g1,{SUBTREE_1}' add_container(inst, SUFFIX, 'exclude') memberof.add('memberOfEntryScopeExcludeSubtree', EXCLUDED_SUBTREE) # Move user to excluded scope user = UserAccount(topo.standalone, dn=INCLUDED_USER) user.rename("uid=test_m1", newsuperior=EXCLUDED_SUBTREE) # Check memberOf and group are cleaned up check_membership(inst, EXCLUDED_USER, GROUP_DN, False) group = Group(topo.standalone, dn=GROUP_DN) assert not group.present("member", EXCLUDED_USER) assert not group.present("member", INCLUDED_USER)
def test_urp_trigger_substring_search(topo_m2): """Test that a ADD of a entry with a '*' in its DN, triggers an internal search with a escaped DN :id: 9869bb39-419f-42c3-a44b-c93eb0b77667 :customerscenario: True :setup: MMR with 2 masters :steps: 1. enable internal operation loggging for plugins 2. Create on M1 a test_user with a '*' in its DN 3. Check the test_user is replicated 4. Check in access logs that the internal search does not contain '*' :expectedresults: 1. Should succeeds 2. Should succeeds 3. Should succeeds 4. Should succeeds """ m1 = topo_m2.ms["master1"] m2 = topo_m2.ms["master2"] # Enable loggging of internal operation logging to capture URP intop log.info('Set nsslapd-plugin-logging to on') for inst in (m1, m2): inst.config.loglevel([AccessLog.DEFAULT, AccessLog.INTERNAL], service='access') inst.config.set('nsslapd-plugin-logging', 'on') inst.restart() # add a user with a DN containing '*' test_asterisk_uid = 'asterisk_*_in_value' test_asterisk_dn = 'uid={},{}'.format(test_asterisk_uid, DEFAULT_SUFFIX) test_user = UserAccount(m1, test_asterisk_dn) if test_user.exists(): log.info('Deleting entry {}'.format(test_asterisk_dn)) test_user.delete() test_user.create( properties={ 'uid': test_asterisk_uid, 'cn': test_asterisk_uid, 'sn': test_asterisk_uid, 'userPassword': test_asterisk_uid, 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/asterisk', }) # check that the ADD was replicated on M2 test_user_m2 = UserAccount(m2, test_asterisk_dn) for i in range(1, 5): if test_user_m2.exists(): break else: log.info('Entry not yet replicated on M2, wait a bit') time.sleep(2) # check that M2 access logs does not "(&(objectclass=nstombstone)(nscpentrydn=uid=asterisk_*_in_value,dc=example,dc=com))" log.info('Check that on M2, URP as not triggered such internal search') pattern = ".*\(Internal\).*SRCH.*\(&\(objectclass=nstombstone\)\(nscpentrydn=uid=asterisk_\*_in_value,dc=example,dc=com.*" found = m2.ds_access_log.match(pattern) log.info("found line: %s" % found) assert not found
def test_gecos_mixed_definition_topo(topo_m2, request): """Check that replication is still working if schema contains definitions that does not conform with a replicated entry :id: d5940e71-d18a-4b71-aaf7-b9185361fffe :setup: Two suppliers replication setup :steps: 1. Create a testuser on M1 2 Stop M1 and M2 3 Change gecos def on M2 to be IA5 4 Update testuser with gecos directoryString value 5 Check replication is still working :expectedresults: 1. success 2. success 3. success 4. success 5. success """ repl = ReplicationManager(DEFAULT_SUFFIX) m1 = topo_m2.ms["supplier1"] m2 = topo_m2.ms["supplier2"] # create a test user testuser_dn = 'uid={},{}'.format('testuser', DEFAULT_SUFFIX) testuser = UserAccount(m1, testuser_dn) try: testuser.create( properties={ 'uid': 'testuser', 'cn': 'testuser', 'sn': 'testuser', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/testuser', }) except ldap.ALREADY_EXISTS: pass repl.wait_for_replication(m1, m2) # Stop suppliers to update the schema m1.stop() m2.stop() # on M1: gecos is DirectoryString (default) # on M2: gecos is IA5 schema_filename = (m2.schemadir + "/99user.ldif") try: with open(schema_filename, 'w') as schema_file: schema_file.write("dn: cn=schema\n") schema_file.write( "attributetypes: ( 1.3.6.1.1.1.1.2 NAME " + "'gecos' DESC 'The GECOS field; the common name' " + "EQUALITY caseIgnoreIA5Match " + "SUBSTR caseIgnoreIA5SubstringsMatch " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 " + "SINGLE-VALUE )\n") os.chmod(schema_filename, 0o777) except OSError as e: log.fatal("Failed to update schema file: " + "{} Error: {}".format(schema_filename, str(e))) # start the instances m1.start() m2.start() # Check that gecos is IA5 on M2 schema = SchemaLegacy(m2) attributetypes = schema.query_attributetype('gecos') assert attributetypes[0].syntax == "1.3.6.1.4.1.1466.115.121.1.26" # Add a gecos UTF value on M1 testuser.replace('gecos', 'Hélène') # Check replication is still working testuser.replace('displayName', 'ascii value') repl.wait_for_replication(m1, m2) testuser_m2 = UserAccount(m2, testuser_dn) assert testuser_m2.exists() assert testuser_m2.get_attr_val_utf8('displayName') == 'ascii value' def fin(): m1.start() m2.start() testuser.delete() repl.wait_for_replication(m1, m2) # on M2 restore a default 99user.ldif m2.stop() os.remove(m2.schemadir + "/99user.ldif") schema_filename = (m2.schemadir + "/99user.ldif") try: with open(schema_filename, 'w') as schema_file: schema_file.write("dn: cn=schema\n") os.chmod(schema_filename, 0o777) except OSError as e: log.fatal("Failed to update schema file: " + "{} Error: {}".format(schema_filename, str(e))) m2.start() m1.start() request.addfinalizer(fin)
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 ''' # Create Managed role entry roles = ManagedRoles(topo.standalone, DEFAULT_SUFFIX) role = roles.create(properties={"cn": 'ROLE1'}) # Create user and Assign the role to the entry uas = UserAccounts(topo.standalone, DEFAULT_SUFFIX, rdn=None) uas.create( properties={ 'uid': 'Fail', 'cn': 'Fail', 'sn': 'user', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + 'Fail', 'nsRoleDN': role.dn, 'userPassword': PW_DM }) # Create user and do not Assign any role to the entry uas.create( properties={ 'uid': 'Success', 'cn': 'Success', 'sn': 'user', 'uidNumber': '1000', 'gidNumber': '2000', 'homeDirectory': '/home/' + 'Success', 'userPassword': PW_DM }) # Assert that Manage role entry is created and its searchable assert ManagedRoles(topo.standalone, DEFAULT_SUFFIX).list()[0].dn \ == 'cn=ROLE1,dc=example,dc=com' # Set an aci that will deny ROLE1 manage role Domain(topo.standalone, DEFAULT_SUFFIX).\ add('aci', '(targetattr=*)(version 3.0; aci "role aci";' ' deny(all) roledn="ldap:///{}";)'.format(role.dn),) # Crate a connection with cn=Fail which is member of ROLE1 conn = UserAccount(topo.standalone, "uid=Fail,{}".format(DEFAULT_SUFFIX)).bind(PW_DM) # Access denied to ROLE1 members assert not ManagedRoles(conn, DEFAULT_SUFFIX).list() # Now create a connection with cn=Success which is not a member of ROLE1 conn = UserAccount(topo.standalone, "uid=Success,{}".format(DEFAULT_SUFFIX)).bind(PW_DM) # Access allowed here assert ManagedRoles(conn, DEFAULT_SUFFIX).list() for i in uas.list(): i.delete() for i in roles.list(): i.delete()
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 attributes being added (or deleted)) "Valueacl Test $tet_thistest Denied by multiple filters." :id:034c6c62-7aaa-11e8-8634-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 = '(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) 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 user = UserAccount(conn, USER_DELADD) user.add("title", "architect") assert user.get_attr_val('title') user.add("secretary", "cn=Meylan,dc=example,dc=com") assert user.get_attr_val('secretary') # aci will allow title some attribute only with pytest.raises(ldap.INSUFFICIENT_ACCESS): user.add("secretary", "cn=Grenoble,dc=example,dc=com")