def test_add_excludescope_with_existing_value(topology): plugin = MemberOfPlugin(topology.standalone) # setup test if not "ou=people,dc=example,dc=com" in plugin.get_excludescope(): plugin.add_excludescope("ou=people,dc=example,dc=com") args = FakeArgs() args.value = "ou=people,dc=example,dc=com" memberof_cli.add_excludescope(topology.standalone, None, topology.logcap.log, args) assert topology.logcap.contains('Value "{}" already exists'.format( args.value)) topology.logcap.flush()
def test_scheme_violation_errors_logged(topo_m2): """Check that ERR messages are verbose enough, if a member entry doesn't have the appropriate objectclass to support 'memberof' attribute :id: e2af0aaa-447e-4e85-a5ce-57ae66260d0b :setup: Standalone instance :steps: 1. Enable memberofPlugin and set autoaddoc to nsMemberOf 2. Restart the instance 3. Add a user without nsMemberOf attribute 4. Create a group and add the user to the group 5. Check that user has memberOf attribute 6. Check the error log for ".*oc_check_allowed_sv.*USER_DN.*memberOf.*not allowed.*" and ".*schema violation caught - repair operation.*" patterns :expectedresults: 1. Should be successful 2. Should be successful 3. Should be successful 4. Should be successful 5. User should have the attribute 6. Errors should be logged """ inst = topo_m2.ms["supplier1"] memberof = MemberOfPlugin(inst) memberof.enable() memberof.set_autoaddoc('nsMemberOf') inst.restart() users = UserAccounts(inst, SUFFIX) user_props = TEST_USER_PROPERTIES.copy() user_props.update({'uid': USER_CN, 'cn': USER_CN, 'sn': USER_CN}) testuser = users.create(properties=user_props) testuser.remove('objectclass', 'nsMemberOf') groups = Groups(inst, SUFFIX) testgroup = groups.create(properties={'cn': GROUP_CN}) testgroup.add('member', testuser.dn) user_memberof_attr = testuser.get_attr_val_utf8('memberof') assert user_memberof_attr log.info('memberOf attr value - {}'.format(user_memberof_attr)) pattern = ".*oc_check_allowed_sv.*{}.*memberOf.*not allowed.*".format(testuser.dn.lower()) log.info("pattern = %s" % pattern) assert inst.ds_error_log.match(pattern) pattern = ".*schema violation caught - repair operation.*" assert inst.ds_error_log.match(pattern)
def config_memberof(server): """Configure memberOf plugin and configure fractional to prevent total init to send memberof """ memberof = MemberOfPlugin(server) memberof.enable() memberof.set_autoaddoc('nsMemberOf') server.restart() agmts = Agreements(server) for agmt in agmts.list(): log.info('update %s to add nsDS5ReplicatedAttributeListTotal' % agmt.dn) agmt.replace_many(('nsDS5ReplicatedAttributeListTotal', '(objectclass=*) $ EXCLUDE '), ('nsDS5ReplicatedAttributeList', '(objectclass=*) $ EXCLUDE memberOf'))
def test_try_remove_all_groupattr_values(topology): plugin = MemberOfPlugin(topology.standalone) # make sure "member" value exists and it is the only one assert "member" in plugin.get_groupattr() # exists from default assert len(plugin.get_groupattr()) == 1 args = FakeArgs() args.value = "member" memberof_cli.remove_groupattr(topology.standalone, None, topology.logcap.log, args) assert topology.logcap.contains( "Error: Failed to delete. memberOfGroupAttr is required.") topology.logcap.flush()
def do_fixup(inst, basedn, log, args): plugin = MemberOfPlugin(inst) log.info('Attempting to add task entry...') if not plugin.status(): log.error("'%s' is disabled. Fix up task can't be executed" % plugin.rdn) return fixup_task = plugin.fixup(args.DN, args.filter) fixup_task.wait() exitcode = fixup_task.get_exit_code() if exitcode != 0: log.error('MemberOf fixup task for %s has failed. Please, check logs') else: log.info('Successfully added task entry')
def test_add_excludescope_with_value_that_exists_in_entryscope(topology): plugin = MemberOfPlugin(topology.standalone) # setup test if not "dc=example,dc=com" in plugin.get_entryscope(): plugin.add_entryscope("dc=example,dc=com") if not "ou=people,dc=example,dc=com" in plugin.get_excludescope(): plugin.add_excludescope("ou=people,dc=example,dc=com") args = FakeArgs() args.value = "ou=people,dc=example,dc=com" memberof_cli.add_scope(topology.standalone, None, topology.logcap.log, args) assert topology.logcap.contains("is also listed as an exclude suffix") topology.logcap.flush()
def config_memberof(server): # Configure fractional to prevent total init to send memberof memberof = MemberOfPlugin(server) memberof.enable() memberof.set_autoaddoc('nsMemberOf') server.restart() ents = server.agreement.list(suffix=DEFAULT_SUFFIX) for ent in ents: log.info('update %s to add nsDS5ReplicatedAttributeListTotal' % ent.dn) server.agreement.setProperties( agmnt_dn=ents[0].dn, properties={ RA_FRAC_EXCLUDE: '(objectclass=*) $ EXCLUDE memberOf', RA_FRAC_EXCLUDE_TOTAL_UPDATE: '(objectclass=*) $ EXCLUDE ' })
def topology(request): topology = default_topology(request) plugin = MemberOfPlugin(topology.standalone) if not plugin.exists(): plugin.create() # At the moment memberof plugin needs to be enabled in order to perform # syntax checking. Additionally, we have to restart the server in order # for the action of enabling the plugin to take effect. plugin.enable() topology.standalone.restart() topology.logcap.flush() return topology
def setup(topology_st, request): """ Enable USN plug-in Enable MEMBEROF plugin Add test entries """ inst = topology_st.standalone log.info("Enable the USN plugin...") plugin = USNPlugin(inst) plugin.enable() log.info("Enable the MEMBEROF plugin...") plugin = MemberOfPlugin(inst) plugin.enable() inst.restart() users_list = [] log.info("Adding test entries...") users = UserAccounts(inst, DEFAULT_SUFFIX) for id in range(USER_NUM): user = users.create_test_user(uid=id) users_list.append(user) groups_list = [] log.info("Adding test groups...") groups = Groups(inst, DEFAULT_SUFFIX) for id in range(GROUP_NUM): group = groups.create(properties={'cn': f'test_group{id}'}) groups_list.append(group) def fin(): for user in users_list: try: user.delete() except ldap.NO_SUCH_OBJECT: pass for group in groups_list: try: group.delete() except ldap.NO_SUCH_OBJECT: pass request.addfinalizer(fin) return {"users": users_list, "groups": groups_list}
def test_no_default_group(automember_fixture, topo): """If memberof is enable and a user became member of default group and default group does not exist then an INFO should be logged :id: 8882972f-fb3e-4d77-9729-0235897676bc :setup: Standalone instance, enabled Auto Membership Plugin :steps: 1. Enable memberof plugin 2. Set errorlog level to 0 (default) 3. delete the default group 4. Create a user 5. Retrieve message in log :expectedresults: 1. Should be success 2. Should be success 3. Should be success 4. Should be success 5. Should be success """ (group, automembers, automember) = automember_fixture from lib389.plugins import MemberOfPlugin memberof = MemberOfPlugin(topo.standalone) memberof.enable() topo.standalone.restart() topo.standalone.setLogLevel(0) # delete it if it exists try: group.get_attr_val_utf8('creatorsname') group.delete() except ldap.NO_SUCH_OBJECT: pass users = UserAccounts(topo.standalone, DEFAULT_SUFFIX) user_1 = users.create_test_user(uid=1) try: error_lines = topo.standalone.ds_error_log.match( '.*auto-membership-plugin - automember_update_member_value - group .default or target. does not exist .%s.$' % group.dn) assert (len(error_lines) > 0) finally: user_1.delete() topo.standalone.setLogLevel(0)
def test_betxn_memberof(topology_st): """Test PLUGIN_MEMBER_OF plugin :id: 70d0b96e-b693-4bf7-bbf5-102a66ac5993 :setup: Standalone instance and enabled dynamic plugins :steps: 1. Enable and configure memberOf plugin 2. Set memberofgroupattr="member" and memberofAutoAddOC="referral" 3. Add two test groups - group1 and group2 4. Add group2 to group1 5. Add group1 to group2 :expectedresults: 1. memberOf plugin plugin should be ON 2. Set memberofgroupattr="member" and memberofAutoAddOC="referral" should PASS 3. Add operation should PASS 4. Add operation should FAIL 5. Add operation should FAIL """ memberof = MemberOfPlugin(topology_st.standalone) memberof.enable() memberof.set_autoaddoc('referral') topology_st.standalone.restart() groups = Groups(topology_st.standalone, DEFAULT_SUFFIX) group1 = groups.create(properties={'cn': 'group1'}) group2 = groups.create(properties={'cn': 'group2'}) # We may need to mod groups to not have nsMemberOf ... ? if not ds_is_older('1.3.7'): group1.remove('objectClass', 'nsMemberOf') group2.remove('objectClass', 'nsMemberOf') # Add group2 to group1 - it should fail with objectclass violation with pytest.raises(ldap.OBJECT_CLASS_VIOLATION): group1.add_member(group2.dn) # verify entry cache reflects the current/correct state of group1 assert not group1.is_member(group2.dn) # Done log.info('test_betxn_memberof: PASSED')
def test_remove_groupattr_with_value_that_exists(topology): plugin = MemberOfPlugin(topology.standalone) # setup test if not "uniquemember" in plugin.get_groupattr(): plugin.add_groupattr("uniquemember") args = FakeArgs() args.value = "uniquemember" memberof_cli.remove_groupattr(topology.standalone, None, topology.logcap.log, args) assert topology.logcap.contains( "successfully removed memberOfGroupAttr value") topology.logcap.flush() memberof_cli.display_groupattr(topology.standalone, None, topology.logcap.log, args) assert not topology.logcap.contains(": uniquemember") topology.logcap.flush()
def test_configuration(topo): """Automembership plugin and mixed in the plugin configuration :id: 45a5a8f8-e800-11e8-ab16-8c16451d917b :setup: Single Instance :steps: 1. Automembership plugin fails in a MMR setup, if data and config area mixed in the plugin configuration 2. Plugin configuration should throw proper error messages if not configured properly :expected results: 1. Should success 2. Should success """ # Configure pluginConfigArea for PLUGIN_AUTO AutoMembershipPlugin(topo.standalone).set("nsslapd-pluginConfigArea", 'cn=config') # Enable MemberOf plugin MemberOfPlugin(topo.standalone).enable() topo.standalone.restart() # Add invalid configuration, which mixes data and config area: All will fail automembers = AutoMembershipDefinitions(topo.standalone) with pytest.raises(ldap.UNWILLING_TO_PERFORM): automembers.create( properties={ 'cn': 'autouserGroups', 'autoMemberScope': f'ou=Employees,cn=config', 'autoMemberFilter': "objectclass=posixAccount", 'autoMemberDefaultGroup': [ f'cn=SuffDef1,ou=autouserGroups,cn=config', f'cn=SuffDef2,ou=autouserGroups,cn=config' ], 'autoMemberGroupingAttr': 'member:dn' }) # Search in error logs assert topo.standalone.ds_error_log.match( '.*ERR - auto-membership-plugin - ' 'automember_parse_config_entry - The default group ' '"cn=SuffDef1,ou=autouserGroups,cn=config" ' 'can not be a child of the plugin config area "cn=config"')
def test_remove_autoaddoc(topology): plugin = MemberOfPlugin(topology.standalone) # setup test if not plugin.get_autoaddoc(): plugin.set_autoaddoc("nsmemberof") args = FakeArgs() # argparse makes sure that only choices 'nsmemberof', 'inetuser', 'inetadmin', 'del' are allowed args.value = "del" memberof_cli.manage_autoaddoc(topology.standalone, None, topology.logcap.log, args) assert topology.logcap.contains("memberOfAutoAddOc attribute deleted") topology.logcap.flush() args.value = None memberof_cli.manage_autoaddoc(topology.standalone, None, topology.logcap.log, args) assert not topology.logcap.contains(": nsMemberOf") topology.logcap.flush()
def test_migrate_openldap_memberof(topology_st): """Attempt a migration with memberof configured, and ensure it migrates :id: f59f4c6a-7c85-40d1-91ee-dccbc0bd7ef8 :setup: Data directory with an openldap config with memberof :steps: 1. Parse the configuration 2. Execute a full migration plan 3. Assert memberof was configured :expectedresults: 1. Success 2. Success 3. Success """ inst = topology_st.standalone config_path = os.path.join(DATADIR1, 'slapd.d') config = olConfig(config_path) for overlay in config.databases[0].overlays: print("==================================================") print("%s" % overlay.otype) print("==================================================") assert overlay.otype != olOverlayType.UNKNOWN ldifs = {} migration = Migration(inst, config.schema, config.databases, ldifs) print("==== migration plan ====") print(migration.__unicode__()) print("==== end migration plan ====") migration.execute_plan() # End test, should suceed with no exceptions. memberof = MemberOfPlugin(inst) assert memberof.status()
def test_delete_default_group(automember_fixture, topo): """If memberof is enable and a user became member of default group because of automember rule then delete the default group should succeeds :id: 8b55d077-8851-45a2-a547-b28a7983a3c2 :setup: Standalone instance, enabled Auto Membership Plugin :steps: 1. Enable memberof plugin 2. Create a user 3. Assert that the user is member of the default group 4. Delete the default group :expectedresults: 1. Should be success 2. Should be success 3. Should be success 4. Should be success """ (group, automembers, automember) = automember_fixture from lib389.plugins import MemberOfPlugin memberof = MemberOfPlugin(topo.standalone) memberof.enable() topo.standalone.restart() topo.standalone.setLogLevel(65536) users = UserAccounts(topo.standalone, DEFAULT_SUFFIX) user_1 = users.create_test_user(uid=1) try: assert group.is_member(user_1.dn) group.delete() error_lines = topo.standalone.ds_error_log.match( '.*auto-membership-plugin - automember_update_member_value - group .default or target. does not exist .%s.$' % group.dn) assert (len(error_lines) == 1) finally: user_1.delete() topo.standalone.setLogLevel(0)
def test_remove_excludescope_with_existing_value(topology): plugin = MemberOfPlugin(topology.standalone) # setup test if not "a=b" in plugin.get_excludescope(): plugin.add_excludescope("a=b") if not "ou=people,dc=example,dc=com" in plugin.get_excludescope(): plugin.add_excludescope("ou=people,dc=example,dc=com") args = FakeArgs() args.value = "a=b" memberof_cli.remove_excludescope(topology.standalone, None, topology.logcap.log, args) assert topology.logcap.contains( "successfully removed memberOfEntryScopeExcludeSubtree value") topology.logcap.flush() args.value = None memberof_cli.display_excludescope(topology.standalone, None, topology.logcap.log, args) assert topology.logcap.contains(": ou=people,dc=example,dc=com") assert not topology.logcap.contains(": a=b") topology.logcap.flush()
def sssd_conf(inst, basedn, log, args): schema_type = "rfc2307" try: mo_plugin = MemberOfPlugin(inst) if mo_plugin.status(): schema_type = "rfc2307bis" except: schema_type = "unknown - likely access denied to memberof plugin config" ldap_access_filter = None if args.allowed_group: groups = Groups(inst, basedn) g_access = groups.get(args.allowed_group) ldap_access_filter = '(memberOf=%s)' % g_access.dn # Print a customised sssd.config. print(SSSD_CONF_TEMPLATE.format( basedn=basedn, schema_type=schema_type, ldap_uri=inst.ldapuri, ldap_access_filter=ldap_access_filter, ))
def _add_user_clean(request): # Enabling memberOf plugin and then adding few groups with member attributes. MemberOfPlugin(SUPPLIER1).enable() for instance in (SUPPLIER1, SUPPLIER2): instance.restart() user1 = UserAccounts(SUPPLIER1, DEFAULT_SUFFIX).create_test_user() for attribute, value in [("displayName", "Anuj Borah"), ("givenName", "aborah"), ("telephoneNumber", "+1 555 999 333"), ("roomnumber", "123"), ("manager", f'uid=dsmith,ou=People,{DEFAULT_SUFFIX}')]: user1.set(attribute, value) grp = Groups(SUPPLIER1, DEFAULT_SUFFIX).create(properties={ "cn": "bug739172_01group", "member": f'uid=test_user_1000,ou=People,{DEFAULT_SUFFIX}' }) def final_call(): """ Removes User and Group after the test. """ user1.delete() grp.delete() request.addfinalizer(final_call)
def sssd_conf(inst, basedn, log, args): schema_type = "rfc2307" try: mo_plugin = MemberOfPlugin(inst) if mo_plugin.status(): schema_type = "rfc2307bis" except: schema_type = "unknown - likely access denied to memberof plugin config" ldap_access_filter = "# ldap_access_filter = (memberOf=<dn>)" if args.allowed_group: groups = Groups(inst, basedn) g_access = groups.get(args.allowed_group) ldap_access_filter = 'ldap_access_filter = (memberOf=%s)' % g_access.dn if inst.ldapuri.startswith("ldapi://"): log.warning( "WARNING: ldap_uri starts with ldapi:// - you should review this parameter in the sssd configuration" ) # Print a customised sssd.config. print( SSSD_CONF_TEMPLATE.format( basedn=basedn, schema_type=schema_type, ldap_uri=inst.ldapuri, ldap_access_filter=ldap_access_filter, )) # Print a customised sssd.conf to log for test purpose log.debug( SSSD_CONF_TEMPLATE.format(basedn=basedn, schema_type=schema_type, ldap_uri=inst.ldapuri, ldap_access_filter=ldap_access_filter))
def configureMO(inst): plugin = MemberOfPlugin(inst) plugin.enable() plugin.replace('memberofgroupattr', 'uniquemember')
def test_delete_target_group(automember_fixture, topo): """If memberof is enabld and a user became member of target group because of automember rule then delete the target group should succeeds :id: bf5745e3-3de8-485d-8a68-e2fd460ce1cb :setup: Standalone instance, enabled Auto Membership Plugin :steps: 1. Recreate the default group if it was deleted before 2. Create a target group (using regex) 3. Create a target group automember rule (regex) 4. Enable memberof plugin 5. Create a user that goes into the target group 6. Assert that the user is member of the target group 7. Delete the target group 8. Check automember skipped the regex automember rule because target group did not exist :expectedresults: 1. Should be success 2. Should be success 3. Should be success 4. Should be success 5. Should be success 6. Should be success 7. Should be success 8. Should be success """ (group, automembers, automember) = automember_fixture # default group that may have been deleted in previous tests try: groups = Groups(topo.standalone, DEFAULT_SUFFIX) group = groups.create(properties={'cn': 'testgroup'}) except: pass # target group that will receive regex automember groups = Groups(topo.standalone, DEFAULT_SUFFIX) group_regex = groups.create(properties={'cn': 'testgroup_regex'}) # regex automember definition automember_regex_prop = { 'cn': 'automember regex', 'autoMemberTargetGroup': group_regex.dn, 'autoMemberInclusiveRegex': 'uid=.*1', } automember_regex_dn = 'cn=automember regex, %s' % automember.dn automember_regexes = AutoMembershipRegexRule(topo.standalone, automember_regex_dn) automember_regex = automember_regexes.create( properties=automember_regex_prop) from lib389.plugins import MemberOfPlugin memberof = MemberOfPlugin(topo.standalone) memberof.enable() topo.standalone.restart() topo.standalone.setLogLevel(65536) # create a user that goes into the target group but not in the default group users = UserAccounts(topo.standalone, DEFAULT_SUFFIX) user_1 = users.create_test_user(uid=1) try: assert group_regex.is_member(user_1.dn) assert not group.is_member(user_1.dn) # delete that target filter group group_regex.delete() error_lines = topo.standalone.ds_error_log.match( '.*auto-membership-plugin - automember_update_member_value - group .default or target. does not exist .%s.$' % group_regex.dn) # one line for default group and one for target group assert (len(error_lines) == 1) finally: user_1.delete() topo.standalone.setLogLevel(0)
def test_sync_repl_cookie_add_del(topology, request): """Test sync_repl cookie are progressing is an increasing order when there add and del :id: 83e11038-6ed0-4a5b-ac77-e44887ab11e3 :setup: Standalone Instance :steps: 1.: enable retroCL 2.: configure retroCL to log nsuniqueid as targetUniqueId 3.: enable content_sync plugin 4.: enable automember 5.: create (2) groups. Few groups can help to reproduce the concurrent updates problem. 6.: configure automember to provision those groups with 'member' 7.: enable and configure memberof plugin 8.: enable plugin log level 9.: restart the server 10.: create a thread dedicated to run a sync repl client 11.: Create (3) users that will generate nested updates (automember/memberof) 12.: Delete (3) users 13.: stop sync repl client and collect the list of cookie.change_no 14.: check that cookies.change_no are in increasing order :expectedresults: 1.: succeeds 2.: succeeds 3.: succeeds 4.: succeeds 5.: succeeds 6.: succeeds 7.: succeeds 8.: succeeds 9.: succeeds 10.: succeeds 11.: succeeds 12.: succeeds 13.: succeeds 14.: succeeds """ inst = topology[0] # Enable/configure retroCL plugin = RetroChangelogPlugin(inst) plugin.disable() plugin.enable() plugin.set('nsslapd-attribute', 'nsuniqueid:targetuniqueid') # Enable sync plugin plugin = ContentSyncPlugin(inst) plugin.enable() # Enable automember plugin = AutoMembershipPlugin(inst) plugin.disable() plugin.enable() # Add the automember group groups = Groups(inst, DEFAULT_SUFFIX) group = [] for i in range(1, 3): group.append(groups.create(properties={'cn': 'group%d' % i})) # Add the automember config entry am_configs = AutoMembershipDefinitions(inst) for g in group: am_config = am_configs.create( properties={ 'cn': 'config %s' % g.get_attr_val_utf8('cn'), 'autoMemberScope': DEFAULT_SUFFIX, 'autoMemberFilter': 'uid=*', 'autoMemberDefaultGroup': g.dn, 'autoMemberGroupingAttr': 'member:dn' }) # Enable and configure memberof plugin plugin = MemberOfPlugin(inst) plugin.disable() plugin.enable() plugin.replace_groupattr('member') memberof_config = MemberOfSharedConfig( inst, 'cn=memberOf config,{}'.format(DEFAULT_SUFFIX)) memberof_config.create( properties={ 'cn': 'memberOf config', 'memberOfGroupAttr': 'member', 'memberOfAttr': 'memberof' }) # Enable plugin log level (usefull for debug) inst.setLogLevel(65536) inst.restart() # create a sync repl client and wait 5 seconds to be sure it is running sync_repl = Sync_persist(inst) sync_repl.start() time.sleep(5) # create users, that automember/memberof will generate nested updates users = UserAccounts(inst, DEFAULT_SUFFIX) users_set = [] for i in range(10001, 10004): users_set.append(users.create_test_user(uid=i)) time.sleep(10) # delete users, that automember/memberof will generate nested updates for user in users_set: user.delete() # stop the server to get the sync_repl result set (exit from while loop). # Only way I found to acheive that. # and wait a bit to let sync_repl thread time to set its result before fetching it. inst.stop() cookies = sync_repl.get_result() # checking that the cookie are in increasing and in an acceptable range (0..1000) assert len(cookies) > 0 prev = 0 for cookie in cookies: log.info('Check cookie %s' % cookie) assert int(cookie) > 0 assert int(cookie) < 1000 assert int(cookie) > prev prev = int(cookie) sync_repl.join() log.info('test_sync_repl_cookie_add_del: PASS\n') def fin(): inst.restart() for g in group: try: g.delete() except: pass request.addfinalizer(fin) return
def apply(self, inst): mo = MemberOfPlugin(inst) try: mo.add_entryscope(self.suffix) except ldap.TYPE_OR_VALUE_EXISTS: pass
def post(self, inst): mo = MemberOfPlugin(inst) task = mo.fixup(self.suffix) task.wait()
def apply(self, inst): mo = MemberOfPlugin(inst) mo.enable()
def test_sync_repl_cookie_with_failure(topology, request): """Test sync_repl cookie are progressing is the right order when there is a failure in nested updates :id: e0103448-170e-4080-8f22-c34606447ce2 :setup: Standalone Instance :steps: 1.: enable retroCL 2.: configure retroCL to log nsuniqueid as targetUniqueId 3.: enable content_sync plugin 4.: enable automember 5.: create (4) groups. make group2 groupOfUniqueNames so the automember will fail to add 'member' (uniqueMember expected) 6.: configure automember to provision those groups with 'member' 7.: enable and configure memberof plugin 8.: enable plugin log level 9.: restart the server 10.: create a thread dedicated to run a sync repl client 11.: Create a group that will be the only update received by sync repl client 12.: Create (9) users that will generate nested updates (automember/memberof) 13.: stop sync repl client and collect the list of cookie.change_no 14.: check that the list of cookie.change_no contains only the group 'step 11' :expectedresults: 1.: succeeds 2.: succeeds 3.: succeeds 4.: succeeds 5.: succeeds 6.: succeeds 7.: succeeds 8.: succeeds 9.: succeeds 10.: succeeds 11.: succeeds 12.: Fails (expected) 13.: succeeds 14.: succeeds """ inst = topology[0] # Enable/configure retroCL plugin = RetroChangelogPlugin(inst) plugin.disable() plugin.enable() plugin.set('nsslapd-attribute', 'nsuniqueid:targetuniqueid') # Enable sync plugin plugin = ContentSyncPlugin(inst) plugin.enable() # Enable automember plugin = AutoMembershipPlugin(inst) plugin.disable() plugin.enable() # Add the automember group groups = Groups(inst, DEFAULT_SUFFIX) group = [] for i in range(1, 5): group.append(groups.create(properties={'cn': 'group%d' % i})) # Set group2 as a groupOfUniqueNames so that automember will fail to update that group # This will trigger a failure in internal MOD and a failure to add member group[1].replace('objectclass', 'groupOfUniqueNames') # Add the automember config entry am_configs = AutoMembershipDefinitions(inst) for g in group: am_config = am_configs.create( properties={ 'cn': 'config %s' % g.get_attr_val_utf8('cn'), 'autoMemberScope': DEFAULT_SUFFIX, 'autoMemberFilter': 'uid=*', 'autoMemberDefaultGroup': g.dn, 'autoMemberGroupingAttr': 'member:dn' }) # Enable and configure memberof plugin plugin = MemberOfPlugin(inst) plugin.disable() plugin.enable() plugin.replace_groupattr('member') memberof_config = MemberOfSharedConfig( inst, 'cn=memberOf config,{}'.format(DEFAULT_SUFFIX)) memberof_config.create( properties={ 'cn': 'memberOf config', 'memberOfGroupAttr': 'member', 'memberOfAttr': 'memberof' }) # Enable plugin log level (usefull for debug) inst.setLogLevel(65536) inst.restart() # create a sync repl client and wait 5 seconds to be sure it is running sync_repl = Sync_persist(inst) sync_repl.start() time.sleep(5) # Add a test group just to check that sync_repl receives only one update group.append(groups.create(properties={'cn': 'group%d' % 10})) # create users, that automember/memberof will generate nested updates users = UserAccounts(inst, DEFAULT_SUFFIX) users_set = [] for i in range(1000, 1010): try: users_set.append(users.create_test_user(uid=i)) # Automember should fail to add uid=1000 in group2 assert (False) except ldap.UNWILLING_TO_PERFORM: pass # stop the server to get the sync_repl result set (exit from while loop). # Only way I found to acheive that. # and wait a bit to let sync_repl thread time to set its result before fetching it. inst.stop() time.sleep(10) cookies = sync_repl.get_result() # checking that the cookie list contains only one entry assert len(cookies) == 1 prev = 0 for cookie in cookies: log.info('Check cookie %s' % cookie) assert int(cookie) > 0 assert int(cookie) < 1000 assert int(cookie) > prev prev = int(cookie) sync_repl.join() log.info('test_sync_repl_cookie_with_failure: PASS\n') def fin(): inst.restart() for user in users_set: try: user.delete() except: pass for g in group: try: g.delete() except: pass request.addfinalizer(fin)
def test_memberof_group(topology_st): """Test memberof does not fail if group is moved into scope :id: 552850aa-agc3-473e-9d39-aae812b46f11 :setup: Single instance :steps: 1. Enable memberof plugin and set memberofentryscope 2. Restart the server 3. Add test sub-suffixes 4. Add test users 5. Add test groups 6. Check for memberof attribute added to the test users 7. Rename the group entry 8. Check the new name is reflected in memberof attribute of user :expectedresults: 1. memberof plugin should be enabled and memberofentryscope should be set 2. Server should be restarted 3. Sub-suffixes should be added 4. Test users should be added 5. Test groups should be added 6. memberof attribute should be present in the test users 7. Group entry should be renamed 8. New group name should be present in memberof attribute of user """ inst = topology_st.standalone log.info( 'Enable memberof plugin and set the scope as cn=sub1,dc=example,dc=com' ) memberof = MemberOfPlugin(inst) memberof.enable() memberof.replace('memberOfEntryScope', SUBTREE_1) inst.restart() add_container(inst, SUFFIX, 'sub1') add_container(inst, SUFFIX, 'sub2') add_member(inst, 'm1', SUBTREE_1) add_member(inst, 'm2', SUBTREE_1) add_group(inst, 'g1', SUBTREE_1) add_group(inst, 'g2', SUBTREE_2) # _check_memberof dn1 = '%s,%s' % ('uid=test_m1', SUBTREE_1) dn2 = '%s,%s' % ('uid=test_m2', SUBTREE_1) g1 = '%s,%s' % ('cn=g1', SUBTREE_1) g2 = '%s,%s' % ('cn=g2', SUBTREE_2) _find_memberof_ext(inst, dn1, g1, True) _find_memberof_ext(inst, dn2, g1, True) _find_memberof_ext(inst, dn1, g2, False) _find_memberof_ext(inst, dn2, g2, False) rename_entry(inst, 'cn=g2', SUBTREE_2, SUBTREE_1) g2n = '%s,%s' % ('cn=g2-new', SUBTREE_1) _find_memberof_ext(inst, dn1, g1, True) _find_memberof_ext(inst, dn2, g1, True) _find_memberof_ext(inst, dn1, g2n, True) _find_memberof_ext(inst, dn2, g2n, True)
def test_memberof_with_changelog_reset(topo_m2): """Test that replication does not break, after DS stop-start, due to changelog reset :id: 60c11636-55a1-4704-9e09-2c6bcc828de4 :setup: 2 Masters :steps: 1. On M1 and M2, Enable memberof 2. On M1, add 999 entries allowing memberof 3. On M1, add a group with these 999 entries as members 4. Stop M1 in between, when add the group memerof is called and before it is finished the add, so step 4 should be executed after memberof has started and before the add has finished 5. Check that replication is working fine :expectedresults: 1. memberof should be enabled 2. Entries should be added 3. Add operation should start 4. M1 should be stopped 5. Replication should be working fine """ m1 = topo_m2.ms["master1"] m2 = topo_m2.ms["master2"] log.info("Configure memberof on M1 and M2") memberof = MemberOfPlugin(m1) memberof.enable() memberof.set_autoaddoc('nsMemberOf') m1.restart() memberof = MemberOfPlugin(m2) memberof.enable() memberof.set_autoaddoc('nsMemberOf') m2.restart() log.info("On M1, add 999 test entries allowing memberof") users_list = add_users(topo_m2, 999, DEFAULT_SUFFIX) log.info("On M1, add a group with these 999 entries as members") dic_of_attributes = { 'cn': ensure_bytes('testgroup'), 'objectclass': ensure_list_bytes(['top', 'groupOfNames']) } for user in users_list: dic_of_attributes.setdefault('member', []) dic_of_attributes['member'].append(user.dn) log.info('Adding the test group using async function') groupdn = 'cn=testgroup,%s' % DEFAULT_SUFFIX m1.add(Entry((groupdn, dic_of_attributes))) #shutdown the server in-between adding the group m1.stop() #start the server m1.start() log.info("Check the log messages for error") error_msg = "ERR - NSMMReplicationPlugin - ruv_compare_ruv" assert not m1.ds_error_log.match(error_msg) log.info("Check that the replication is working fine both ways, M1 <-> M2") repl = ReplicationManager(DEFAULT_SUFFIX) repl.test_replication_topology(topo_m2)
def test_memberof_with_repl(topo): """Test that we allowed to enable MemberOf plugin in dedicated consumer :id: 60c11636-55a1-4704-9e09-2c6bcc828de4 :setup: 1 Master - 1 Hub - 1 Consumer :steps: 1. Configure replication to EXCLUDE memberof 2. Enable memberof plugin 3. Create users/groups 4. Make user_0 member of group_0 5. Checks that user_0 is memberof group_0 on M,H,C 6. Make group_0 member of group_1 (nest group) 7. Checks that user_0 is memberof group_0 and group_1 on M,H,C 8. Check group_0 is memberof group_1 on M,H,C 9. Remove group_0 from group_1 10. Check group_0 and user_0 are NOT memberof group_1 on M,H,C 11. Remove user_0 from group_0 12. Check user_0 is not memberof group_0 and group_1 on M,H,C 13. Disable memberof on C 14. make user_0 member of group_1 15. Checks that user_0 is memberof group_0 on M,H but not on C 16. Enable memberof on C 17. Checks that user_0 is memberof group_0 on M,H but not on C 18. Run memberof fixup task 19. Checks that user_0 is memberof group_0 on M,H,C :expectedresults: 1. Configuration should be successful 2. Plugin should be enabled 3. Users and groups should be created 4. user_0 should be member of group_0 5. user_0 should be memberof group_0 on M,H,C 6. group_0 should be member of group_1 7. user_0 should be memberof group_0 and group_1 on M,H,C 8. group_0 should be memberof group_1 on M,H,C 9. group_0 from group_1 removal should be successful 10. group_0 and user_0 should not be memberof group_1 on M,H,C 11. user_0 from group_0 remove should be successful 12. user_0 should not be memberof group_0 and group_1 on M,H,C 13. memberof should be disabled on C 14. user_0 should be member of group_1 15. user_0 should be memberof group_0 on M,H and should not on C 16. Enable memberof on C should be successful 17. user_0 should be memberof group_0 on M,H should not on C 18. memberof fixup task should be successful 19. user_0 should be memberof group_0 on M,H,C """ M1 = topo.ms["master1"] H1 = topo.hs["hub1"] C1 = topo.cs["consumer1"] # Step 1 & 2 M1.config.enable_log('audit') config_memberof(M1) M1.restart() H1.config.enable_log('audit') config_memberof(H1) H1.restart() C1.config.enable_log('audit') config_memberof(C1) C1.restart() #Declare lists of users and groups test_users = [] test_groups = [] # Step 3 #In for loop create users and add them in the user list #it creates user_0 to user_9 (range is fun) for i in range(10): CN = '%s%d' % (USER_CN, i) users = UserAccounts(M1, SUFFIX) user_props = TEST_USER_PROPERTIES.copy() user_props.update({'uid': CN, 'cn': CN, 'sn': '_%s' % CN}) testuser = users.create(properties=user_props) time.sleep(2) test_users.append(testuser) #In for loop create groups and add them to the group list #it creates group_0 to group_2 (range is fun) for i in range(3): CN = '%s%d' % (GROUP_CN, i) groups = Groups(M1, SUFFIX) testgroup = groups.create(properties={'cn': CN}) time.sleep(2) test_groups.append(testgroup) # Step 4 #Now start testing by adding differnt user to differn group if not ds_is_older('1.3.7'): test_groups[0].remove('objectClass', 'nsMemberOf') member_dn = test_users[0].dn grp0_dn = test_groups[0].dn grp1_dn = test_groups[1].dn test_groups[0].add_member(member_dn) time.sleep(5) # Step 5 for i in [M1, H1, C1]: _find_memberof(i, member_dn, grp0_dn) # Step 6 test_groups[1].add_member(test_groups[0].dn) time.sleep(5) # Step 7 for i in [grp0_dn, grp1_dn]: for inst in [M1, H1, C1]: _find_memberof(inst, member_dn, i) # Step 8 for i in [M1, H1, C1]: _find_memberof(i, grp0_dn, grp1_dn) # Step 9 test_groups[1].remove_member(test_groups[0].dn) time.sleep(5) # Step 10 # For negative testcase, we are using assertionerror for inst in [M1, H1, C1]: for i in [grp0_dn, member_dn]: with pytest.raises(AssertionError): _find_memberof(inst, i, grp1_dn) # Step 11 test_groups[0].remove_member(member_dn) time.sleep(5) # Step 12 for inst in [M1, H1, C1]: for grp in [grp0_dn, grp1_dn]: with pytest.raises(AssertionError): _find_memberof(inst, member_dn, grp) # Step 13 C1.plugins.disable(name=PLUGIN_MEMBER_OF) C1.restart() # Step 14 test_groups[0].add_member(member_dn) time.sleep(5) # Step 15 for i in [M1, H1]: _find_memberof(i, member_dn, grp0_dn) with pytest.raises(AssertionError): _find_memberof(C1, member_dn, grp0_dn) # Step 16 memberof = MemberOfPlugin(C1) memberof.enable() C1.restart() # Step 17 for i in [M1, H1]: _find_memberof(i, member_dn, grp0_dn) with pytest.raises(AssertionError): _find_memberof(C1, member_dn, grp0_dn) # Step 18 memberof.fixup(SUFFIX) time.sleep(5) # Step 19 for i in [M1, H1, C1]: _find_memberof(i, member_dn, grp0_dn)