def remove_autoaddoc(inst, basedn, log, args): plugin = MemberOfPlugin(inst) if not plugin.get_autoaddoc(): log.info("memberOfAutoAddOc was not set") else: plugin.remove_autoaddoc() log.info("memberOfAutoAddOc attribute deleted")
def display_excludescope(inst, basedn, log, args): plugin = MemberOfPlugin(inst) val = plugin.get_excludescope_formatted() if not val: log.info("memberOfEntryScopeExcludeSubtree is not set") else: log.info(val)
def display_autoaddoc(inst, basedn, log, args): plugin = MemberOfPlugin(inst) val = plugin.get_autoaddoc_formatted() if not val: log.info("memberOfAutoAddOc is not set") else: log.info(val)
def test_unindexed_internal_search_crashes_server(topo, add_a_group_with_users, set_small_idlistscanlimit): """ An internal unindexed search was able to crash the server due to missing logging function. :id: 2d0e4070-96d6-46e5-b2c8-9495925e3e87 :customerscenario: True :setup: Standalone instance :steps: 1. Add a group with users 2. Change nsslapd-idlistscanlimit to a smaller value to accelerate the reproducer 3. Enable memberOf plugin 4. Restart the instance 5. Run memberOf fixup task 6. Wait for the task to complete :expectedresults: 1. Should succeed 2. Should succeed 3. Should succeed 4. Should succeed 5. Should succeed 6. Server should not crash """ inst = topo.standalone memberof = MemberOfPlugin(inst) memberof.enable() inst.restart() task = memberof.fixup(DEFAULT_SUFFIX) task.wait() assert inst.status()
def _enable_plugins(inst, group_dn): # Enable automember amp = AutoMembershipPlugin(inst) amp.enable() # Create the automember definition automembers = AutoMembershipDefinitions(inst) automember = automembers.create( properties={ 'cn': 'testgroup_definition', 'autoMemberScope': DEFAULT_SUFFIX, 'autoMemberFilter': 'objectclass=nsAccount', 'autoMemberDefaultGroup': group_dn, 'autoMemberGroupingAttr': 'member:dn', }) # Enable MemberOf mop = MemberOfPlugin(inst) mop.enable() # Enable referint rip = ReferentialIntegrityPlugin(inst) # We only need to enable the plugin, the default configuration is sane and # correctly coveres member as an enforced attribute. rip.enable() # Restart to make sure it's enabled and good to go. inst.restart()
def test_dsidm_config_sssd(topology_st, set_log_file): """ Test dsidm creation of sssd.conf content :id: 77812ba6-b133-40f4-91a7-13309618f24d :setup: Standalone instance :steps: 1. Run dsidm client_config sssd.conf 2. Enable MemberOfPlugin 3. Run dsidm client_config sssd.conf with allowed group :expectedresults: 1. Success 2. Success 3. Success """ standalone = topology_st.standalone sssd_content_list = [ 'Generated by 389 Directory Server - dsidm', 'id_provider = ldap', 'auth_provider = ldap', 'access_provider = ldap', 'chpass_provider = ldap', 'ldap_search_base = ' + DEFAULT_SUFFIX, 'ldap_uri = ' + standalone.ldapuri, 'ldap_user_member_of = memberof', 'ignore_group_members = False', '[sssd]', 'services = nss, pam, ssh, sudo', 'config_file_version = 2', 'domains = ldap', '[nss]', 'homedir_substring = /home' ] schema = 'ldap_schema = rfc2307' args = FakeArgs() args.allowed_group = None log.info('Create sssd.conf content') sssd_conf(standalone, DEFAULT_SUFFIX, log, args) log.info('Check if config creation was successful') check_value_in_log_and_reset(sssd_content_list, check_value=schema) log.info('Now we test allowed_group argument') log.info('Enable MemberOf plugin') plugin = MemberOfPlugin(standalone) plugin.enable() standalone.restart() log.info('Create test group') groups = Groups(standalone, DEFAULT_SUFFIX) test_group = groups.create(properties={ "cn": "new_group", "description": "testgroup" }) log.info('Create sssd.conf content with allowed group') filter_msg = [ 'ldap_access_filter = (memberOf={})'.format(test_group.dn), 'ldap_schema = rfc2307bis' ] args.allowed_group = test_group.rdn sssd_conf(standalone, DEFAULT_SUFFIX, log, args) log.info('Check if config creation was successful') check_value_in_log_and_reset(sssd_content_list, filter_msg)
def display(inst, basedn, log, args): users = nsUserAccounts(inst, basedn) groups = Groups(inst, basedn) 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" # Get required information print( DISPLAY_TEMPLATE.format( ldap_uri=inst.ldapuri, ldap_dns_uri=basedn_to_ldap_dns_uri(basedn), basedn=basedn, schema_type=schema_type, user_basedn=users._basedn, user_filter=users._get_objectclass_filter(), user_id_filter=users._get_selector_filter('<PARAM>'), group_basedn=groups._basedn, group_filter=groups._get_objectclass_filter(), group_id_filter=groups._get_selector_filter('<PARAM>'), uuid_attr='nsUniqueId', user_rdn=users._filterattrs[0], group_rdn=groups._filterattrs[0], group_member='member', ))
def display_allbackends(inst, basedn, log, args): plugin = MemberOfPlugin(inst) val = plugin.get_allbackends_formatted() if not val: log.info("memberOfAllBackends is not set") else: log.info(val)
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 ldap_uri_warning = "" if inst.ldapuri.startswith("ldapi://"): ldap_uri_warning = "# ⚠️ WARNING: ldap_uri starts with ldapi:// - you should review this parameter" # 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, ldap_uri_warning=ldap_uri_warning)) # 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, ldap_uri_warning=ldap_uri_warning))
def display_skipnested(inst, basedn, log, args): plugin = MemberOfPlugin(inst) val = plugin.get_skipnested_formatted() if not val: log.info("memberOfSkipNested is not set") else: log.info(val)
def test_notice_when_dynamic_not_enabled(topology): """ Test to show the logged noticed when dynamic plugins is disabled. :id: e4923789-c187-44b0-8734-34f26cbae06e :setup: Standalone instance :steps: 1. Ensure Dynamic Plugins is disabled 2. Enable a plugin :expectedresults: 1. Success 2. Notice generated """ st = topology.standalone st.config.set("nsslapd-dynamic-plugins", "off") st.restart() mo = MemberOfPlugin(st) mo.enable() # Now check the error log. pattern = ".*nsslapd-dynamic-plugins is off.*" assert st.ds_error_log.match(pattern)
def remove_excludescope(inst, basedn, log, args): plugin = MemberOfPlugin(inst) try: plugin.remove_excludescope(args.value) except ldap.NO_SUCH_ATTRIBUTE: log.error('Error: Failed to delete. No value "{0}" found.'.format(args.value)) else: log.info('successfully removed memberOfEntryScopeExcludeSubtree value "{}"'.format(args.value))
def set_attr(inst, basedn, log, args): plugin = MemberOfPlugin(inst) try: plugin.set_attr(args.value) except ldap.UNWILLING_TO_PERFORM: log.error('Error: Illegal value "{}". Failed to set.'.format(args.value)) else: log.info('memberOfAttr set to "{}"'.format(args.value))
def post(self, inst): # Check if dynamic config is on, because that will affect if fixup will work. if inst.config.get_attr_val_utf8("nsslapd-dynamic-plugins") == "on": self.dynamic = True if self.dynamic: mo = MemberOfPlugin(inst) task = mo.fixup(self.suffix) task.wait()
def remove_groupattr(inst, basedn, log, args): plugin = MemberOfPlugin(inst) try: plugin.remove_groupattr(args.value) except ldap.UNWILLING_TO_PERFORM: log.error("Error: Failed to delete. memberOfGroupAttr is required.") except ldap.NO_SUCH_ATTRIBUTE: log.error('Error: Failed to delete. No value "{0}" found.'.format(args.value)) else: log.info('successfully removed memberOfGroupAttr value "{}"'.format(args.value))
def add_groupattr(inst, basedn, log, args): plugin = MemberOfPlugin(inst) try: plugin.add_groupattr(args.value) except ldap.UNWILLING_TO_PERFORM: log.error('Error: Illegal value "{}". Failed to add.'.format(args.value)) except ldap.TYPE_OR_VALUE_EXISTS: log.info('Value "{}" already exists.'.format(args.value)) else: log.info('successfully added memberOfGroupAttr value "{}"'.format(args.value))
def test_dsidm_config_display(topology_st, set_log_file): """ Test dsidm display option :id: 6e888ae2-8835-44d5-846b-e971d76aa461 :setup: Standalone instance :steps: 1. Run dsidm client_config display 2. Enable MemberOfPlugin 3. Run dsidm client_config display with MemberOfPlugin :expectedresults: 1. Success 2. Success 3. Success """ standalone = topology_st.standalone users = nsUserAccounts(standalone, DEFAULT_SUFFIX) groups = Groups(standalone, DEFAULT_SUFFIX) display_content_list = [ 'ldap_uri = ' + standalone.ldapuri, 'ldap_uri = ldaps:///dc%3Dexample%2Cdc%3Dcom', 'group_basedn = ' + groups._basedn, 'basedn = ' + DEFAULT_SUFFIX, 'user_basedn = ' + users._basedn, 'user_filter = (&(objectclass=nsPerson)(objectclass=nsAccount)(objectclass=nsOrgPerson)' '(objectclass=posixAccount))', 'unique id = nsUniqueId', 'group member attribute = member', 'user rdn = uid', 'user identifier = uid', 'group_filter = (&(objectclass=groupOfNames))', 'group rdn = cn' ] schema_type = 'rfc2307' args = FakeArgs() log.info('Test dsidm display option') display(standalone, DEFAULT_SUFFIX, log, args) log.info('Check if display option was successful') check_value_in_log_and_reset(display_content_list, check_value=schema_type) log.info('Enable MemberOf plugin') plugin = MemberOfPlugin(standalone) plugin.enable() standalone.restart() log.info('Test dsidm display option with MemberOf plugin') display(standalone, DEFAULT_SUFFIX, log, args) log.info( 'Check if display option was successful with MemberOf plugin enabled') schema_type = 'rfc2307bis' check_value_in_log_and_reset(display_content_list, check_value=schema_type)
def test_betxn_modrdn_memberof_cache_corruption(topology_st): """Test modrdn operations and memberOf be txn post op failures :id: 70d0b96e-b693-4bf7-bbf5-102a66ac5994 :setup: Standalone instance :steps: 1. Enable and configure memberOf plugin 2. Set memberofgroupattr="member" and memberofAutoAddOC="nsContainer" 3. Create group and user outside of memberOf plugin scope 4. Do modrdn to move group into scope 5. Do modrdn to move group into scope (again) :expectedresults: 1. memberOf plugin plugin should be ON 2. Set memberofgroupattr="member" and memberofAutoAddOC="nsContainer" should PASS 3. Creating group and user should PASS 4. Modrdn should fail with objectclass violation 5. Second modrdn should also fail with objectclass violation """ peoplebase = 'ou=people,%s' % DEFAULT_SUFFIX memberof = MemberOfPlugin(topology_st.standalone) memberof.enable() memberof.set_autoaddoc('nsContainer') # Bad OC memberof.set('memberOfEntryScope', peoplebase) memberof.set('memberOfAllBackends', 'on') topology_st.standalone.restart() groups = Groups(topology_st.standalone, DEFAULT_SUFFIX) group = groups.create(properties={ 'cn': 'group', }) # Create user and add it to group users = UserAccounts(topology_st.standalone, basedn=DEFAULT_SUFFIX) user = users.ensure_state(properties=TEST_USER_PROPERTIES) if not ds_is_older('1.3.7'): user.remove('objectClass', 'nsMemberOf') group.add_member(user.dn) # Attempt modrdn that should fail, but the original entry should stay in the cache with pytest.raises(ldap.OBJECT_CLASS_VIOLATION): group.rename('cn=group_to_people', newsuperior=peoplebase) # Should fail, but not with NO_SUCH_OBJECT as the original entry should still be in the cache with pytest.raises(ldap.OBJECT_CLASS_VIOLATION): group.rename('cn=group_to_people', newsuperior=peoplebase) # Done log.info('test_betxn_modrdn_memberof: PASSED')
def test_set_groupattr_with_value_that_already_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.add_groupattr(topology.standalone, None, topology.logcap.log, args) assert topology.logcap.contains("already exists") topology.logcap.flush()
def test_get_autoaddoc_when_not_set(topology): plugin = MemberOfPlugin(topology.standalone) # setup test if plugin.get_autoaddoc(): plugin.remove_autoaddoc() args = FakeArgs() args.value = None memberof_cli.manage_autoaddoc(topology.standalone, None, topology.logcap.log, args) assert topology.logcap.contains("memberOfAutoAddOc is not set") topology.logcap.flush()
def add_excludescope(inst, basedn, log, args): plugin = MemberOfPlugin(inst) try: plugin.add_excludescope(args.value) except ldap.UNWILLING_TO_PERFORM as ex: if "is also listed as an exclude suffix" in ex.args[0]['info']: log.error('Error: Suffix ({0}) is listed in entry scope.'.format(args.value)) else: log.error('Error: Invalid DN "{}". Failed to add.'.format(args.value)) except ldap.TYPE_OR_VALUE_EXISTS: log.info('Value "{}" already exists.'.format(args.value)) else: log.info('successfully added memberOfEntryScopeExcludeSubtree value "{}"'.format(args.value))
def memberof_add_config(inst, basedn, log, args): log = log.getChild('memberof_add_config') targetdn = args.DN config = generic_object_add(MemberOfSharedConfig, inst, log, args, arg_to_attr, dn=targetdn) plugin = MemberOfPlugin(inst) plugin.replace('nsslapd-pluginConfigArea', config.dn) log.info('MemberOf attribute nsslapd-pluginConfigArea (config-entry) ' 'was set in the main plugin config')
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_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 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_remove_all_excludescope(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 = None memberof_cli.display_excludescope(topology.standalone, None, topology.logcap.log, args) assert topology.logcap.contains(": a=b") assert topology.logcap.contains(": ou=people,dc=example,dc=com") topology.logcap.flush() args.value = None memberof_cli.remove_all_excludescope(topology.standalone, None, topology.logcap.log, args) assert topology.logcap.contains( "successfully removed all memberOfEntryScopeExcludeSubtree values") topology.logcap.flush() args.value = None memberof_cli.display_excludescope(topology.standalone, None, topology.logcap.log, args) assert not topology.logcap.contains(": a=b") assert not topology.logcap.contains(": ou=people,dc=example,dc=com") 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 _add_user_clean(request): # Enabling memberOf plugin and then adding few groups with member attributes. MemberOfPlugin(MASTER1).enable() for instance in (MASTER1, MASTER2): instance.restart() user1 = UserAccounts(MASTER1, 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(MASTER1, 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 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_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()