def password_change(inst, basedn, log, args): # Due to an issue, we can't use extended op, so we have to # submit the password directly to the field. password = _get_arg(args.password, msg="Enter new directory manager password", hidden=True, confirm=True) dm = DirectoryManager(inst) dm.change_password(password)
def run(self): """Start adding users""" dm = DirectoryManager(self.inst) conn = dm.bind() users = UserAccounts(conn, DEFAULT_SUFFIX) u_range = list(range(self.num_users)) random.shuffle(u_range) for idx in u_range: try: users.create( properties={ 'uid': 'testuser%s' % idx, 'cn': 'testuser%s' % idx, 'sn': 'user%s' % idx, 'uidNumber': '%s' % (1000 + idx), 'gidNumber': '%s' % (1000 + idx), 'homeDirectory': '/home/testuser%s' % idx }) # One of the masters was probably put into read only mode - just break out except ldap.UNWILLING_TO_PERFORM: break except ldap.ALREADY_EXISTS: pass conn.close()
def test_plugin_bind_dn_tracking_and_replication(topo_m2): """Testing nsslapd-plugin-binddn-tracking does not cause issues around access control and reconfiguring replication/repl agmt. :id: dd689d03-69b8-4bf9-a06e-2acd19d5e2c9 :setup: 2 supplier topology :steps: 1. Turn on plugin binddn tracking 2. Add some users 3. Make an update as a user 4. Make an update to the replica config 5. Make an update to the repliocation agreement :expectedresults: 1. Success 2. Success 3. Success 4. Success 5. Success """ m1 = topo_m2.ms["supplier1"] # Turn on bind dn tracking m1.config.set('nsslapd-plugin-binddn-tracking', 'on') # Add two users users = UserAccounts(m1, DEFAULT_SUFFIX) user1 = users.create_test_user(uid=1011) user1.set('userpassword', PASSWORD) user2 = users.create_test_user(uid=1012) # Add an aci acival = '(targetattr ="cn")(version 3.0;acl "Test bind dn tracking"' + \ ';allow (all) (userdn = "ldap:///{}");)'.format(user1.dn) Domain(m1, DEFAULT_SUFFIX).add('aci', acival) # Bind as user and make an update user1.rebind(PASSWORD) user2.set('cn', 'new value') dm = DirectoryManager(m1) dm.rebind() # modify replica replica = Replicas(m1).get(DEFAULT_SUFFIX) replica.set(REPL_PROTOCOL_TIMEOUT, "30") # modify repl agmt agmt = replica.get_agreements().list()[0] agmt.set(REPL_PROTOCOL_TIMEOUT, "20")
def run(self): # Add 1000 entries log.info('Run.') conn = DirectoryManager(self.inst.standalone).bind() time.sleep(30) log.info('Adding users.') for i in range(1000): user = UserAccounts(conn, DEFAULT_SUFFIX) users = user.create_test_user(uid=i) users.delete() self._ran = True if self._should_stop: break if not self._should_stop: raise RuntimeError('We finished too soon.') conn.close()
def test_ldbm_modification_audit_log(topology_st): """When updating LDBM config attributes, those attributes/values are not listed in the audit log :id: 5bf75c47-a283-430e-a65c-3c5fd8dbadb8 :setup: Standalone Instance :steps: 1. Bind as DM 2. Enable audit log 3. Update a set of config attrs in LDBM config 4. Restart the server 5. Check that config attrs are listed in the audit log :expectedresults: 1. Operation successful 2. Operation successful 3. Operation successful 4. Operation successful 5. Audit log should contain modification of attrs" """ VALUE = '10001' d_manager = DirectoryManager(topology_st.standalone) conn = d_manager.bind() config_ldbm = LDBMConfig(conn) log.info("Enable audit logging") conn.config.enable_log('audit') attrs = [ 'nsslapd-lookthroughlimit', 'nsslapd-pagedidlistscanlimit', 'nsslapd-idlistscanlimit', 'nsslapd-db-locks' ] for attr in attrs: log.info("Set attribute %s to value %s" % (attr, VALUE)) config_ldbm.set(attr, VALUE) log.info('Restart the server to flush the logs') conn.restart() for attr in attrs: log.info("Check if attribute %s is replaced in the audit log" % attr) assert conn.searchAuditLog('replace: %s' % attr) assert conn.searchAuditLog('%s: %s' % (attr, VALUE))
def run(self): """Keep opening and closing connections""" idx = 0 err_count = 0 global STOP while idx < MAX_CONNS and not STOP: try: conn = DirectoryManager(self.inst).bind(connOnly=True) conn.unbind_s() time.sleep(.2) err_count = 0 except ldap.LDAPError as e: err_count += 1 if err_count > 3: log.error('BindOnlyConn exiting thread: %s' % (str(e))) return time.sleep(.4) idx += 1
def test_ldap_auth_token_directory_manager(topology): """ Test token auth with directory manager is denied :id: ec9aec64-3edf-4f3f-853a-7527b0c42124 :setup: Standalone instance :steps: 1. Attempt to generate a token as DM :expectedresults: 1. Fails """ topology.standalone.enable_tls() topology.standalone.config.set('nsslapd-enable-ldapssotoken', 'on') # enable it. dm = DirectoryManager(topology.standalone) # Try getting a token at DM, should fail. with pytest.raises(ldap.UNWILLING_TO_PERFORM): dm.request_sso_token()
def run(self): global RUNNING conn = DirectoryManager(self.inst).bind() while RUNNING: time.sleep(2) try: conn.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'objectclass=top') except ldap.LDAPError as e: log.fatal('Full Search Users: Search failed (%s): %s' % ('objectclass=*', e.message['desc'])) conn.close() assert False conn.close()
def run(self): """ Start adding users """ idx = 0 conn = DirectoryManager(self.inst).bind() domain = Domain(conn, DEFAULT_SUFFIX) while idx < MOD_COUNT: try: domain.replace('description', str(idx)) except: if self.task == "import": # Failures are expected during an import pass else: # export, should not fail log.fatal('Updates should not fail during an export') assert False idx += 1
def user(topology_st, request): """Add and remove a test user""" dm = DirectoryManager(topology_st.standalone) # Add aci so users can change their own password USER_ACI = '(targetattr="userpassword || passwordHistory")(version 3.0; acl "pwp test"; allow (all) userdn="ldap:///self";)' ous = OrganizationalUnits(topology_st.standalone, DEFAULT_SUFFIX) ou = ous.get('people') ou.add('aci', USER_ACI) # Create a user users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX) user = users.create_test_user() user.set('userpassword', USER_PWD) def fin(): dm.rebind() user.delete() ou.remove('aci', USER_ACI) request.addfinalizer(fin) return user
def run(self): # Equality conn = DirectoryManager(self.inst).bind() idx = 0 while idx < NUM_USERS: search_filter = ('(|(uid=supplier' + self.id + '_entry' + str(idx) + ')(cn=supplier' + self.id + '_entry' + str(idx) + '))') try: conn.search(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, search_filter) except ldap.LDAPError as e: log.fatal('Search Users: Search failed (%s): %s' % (search_filter, e.message['desc'])) conn.close() return idx += 1 conn.close() # Substring conn = DirectoryManager(self.inst).bind() idx = 0 while idx < NUM_USERS: search_filter = ('(|(uid=supplier' + self.id + '_entry' + str(idx) + '*)(cn=supplier' + self.id + '_entry' + str(idx) + '*))') try: conn.search(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, search_filter) except ldap.LDAPError as e: log.fatal('Search Users: Search failed (%s): %s' % (search_filter, e.message['desc'])) conn.close() return idx += 1 conn.close()
def run(self): # Mod existing entries conn = DirectoryManager(self.inst).bind() idx = 0 while idx < NUM_USERS: USER_DN = ('uid=supplier' + self.id + '_entry' + str(idx) + ',' + DEFAULT_SUFFIX) try: conn.modify(USER_DN, [(ldap.MOD_REPLACE, 'givenname', 'new givenname supplier1-' + str(idx))]) except ldap.LDAPError as e: log.fatal('Failed to modify (' + USER_DN + ') on supplier ' + self.id + ': error ' + e.message['desc']) idx += 1 conn.close() # Modrdn existing entries conn = DirectoryManager(self.inst).bind() idx = 0 while idx < NUM_USERS: USER_DN = ('uid=supplier' + self.id + '_entry' + str(idx) + ',' + DEFAULT_SUFFIX) NEW_RDN = 'cn=supplier' + self.id + '_entry' + str(idx) try: conn.rename_s(USER_DN, NEW_RDN, delold=1) except ldap.LDAPError as e: log.error('Failed to modrdn (' + USER_DN + ') on supplier ' + self.id + ': error ' + e.message['desc']) idx += 1 conn.close() # Undo modrdn to we can rerun this test conn = DirectoryManager(self.inst).bind() idx = 0 while idx < NUM_USERS: USER_DN = ('cn=supplier' + self.id + '_entry' + str(idx) + ',' + DEFAULT_SUFFIX) NEW_RDN = 'uid=supplier' + self.id + '_entry' + str(idx) try: conn.rename_s(USER_DN, NEW_RDN, delold=1) except ldap.LDAPError as e: log.error('Failed to modrdn (' + USER_DN + ') on supplier ' + self.id + ': error ' + e.message['desc']) idx += 1 conn.close()
def run(self): # Add 5000 entries idx = 0 RDN = 'uid=add_del_supplier_' + self.id + '-' conn = DirectoryManager(self.inst).bind() while idx < NUM_USERS: USER_DN = RDN + str(idx) + ',' + DEFAULT_SUFFIX try: conn.add_s( Entry((USER_DN, { 'objectclass': 'top extensibleObject'.split(), 'uid': 'user' + str(idx), 'cn': 'g' * random.randint(1, 500) }))) except ldap.LDAPError as e: log.fatal('Add users to supplier ' + self.id + ' failed (' + USER_DN + ') error: ' + e.message['desc']) idx += 1 conn.close() # Delete 5000 entries conn = DirectoryManager(self.inst).bind() idx = 0 while idx < NUM_USERS: USER_DN = RDN + str(idx) + ',' + DEFAULT_SUFFIX try: conn.delete_s(USER_DN) except ldap.LDAPError as e: log.fatal('Failed to delete (' + USER_DN + ') on supplier ' + self.id + ': error ' + e.message['desc']) idx += 1 conn.close()
def test_basic(topology_st, user): """Test basic password policy history feature functionality :id: 83d74f7d-3036-4944-8839-1b40bbf265ff :setup: Standalone instance, a test user :steps: 1. Configure password history policy as bellow: passwordHistory: on passwordInHistory: 3 passwordChange: on passwordStorageScheme: CLEAR 2. Attempt to change password to the same password 3. Change password four times 4. Check that we only have 3 passwords stored in history 5. Attempt to change the password to previous passwords 6. Reset password by Directory Manager (admin reset) 7. Try and change the password to the previous password before the reset 8. Test passwordInHistory set to "0" rejects only the current password 9. Test passwordInHistory set to "2" rejects previous passwords :expectedresults: 1. Password history policy should be configured successfully 2. Password change should be correctly rejected with Constrant Violation error 3. Password should be successfully changed 4. Only 3 passwords should be stored in history 5. Password changes should be correctly rejected with Constrant Violation error 6. Password should be successfully reset 7. Password change should be correctly rejected with Constrant Violation error 8. Success 9. Success """ # # Configure password history policy and add a test user # try: topology_st.standalone.config.replace_many( ('passwordHistory', 'on'), ('passwordInHistory', '3'), ('passwordChange', 'on'), ('passwordStorageScheme', 'CLEAR'), ('nsslapd-auditlog-logging-enabled', 'on')) log.info('Configured password policy.') except ldap.LDAPError as e: log.fatal('Failed to configure password policy: ' + str(e)) assert False time.sleep(1) # Bind as the test user user.rebind(USER_PWD) # # Test that password history is enforced. # # Attempt to change password to the same password try: user.set('userpassword', 'password') log.info('Incorrectly able to to set password to existing password.') assert False except ldap.CONSTRAINT_VIOLATION: log.info('Password change correctly rejected') except ldap.LDAPError as e: log.fatal('Failed to attempt to change password: '******'userpassword', 'password1') user.rebind('password1') time.sleep(.5) user.set('userpassword', 'password2') user.rebind('password2') time.sleep(.5) user.set('userpassword', 'password3') user.rebind('password3') time.sleep(.5) user.set('userpassword', 'password4') user.rebind('password4') time.sleep(.5) # # Check that we only have 3 passwords stored in history # pwds = user.get_attr_vals('passwordHistory') if len(pwds) != 3: log.fatal('Incorrect number of passwords stored in history: %d' % len(pwds)) log.error('password history: ' + str(pwds)) assert False else: log.info('Correct number of passwords found in history.') # # Attempt to change the password to previous passwords # try: user.set('userpassword', 'password1') log.fatal('Incorrectly able to to set password to previous password1.') log.fatal('password history: ' + str(user.get_attr_vals('passwordhistory'))) assert False except ldap.CONSTRAINT_VIOLATION: log.info('Password change correctly rejected') except ldap.LDAPError as e: log.fatal('Failed to attempt to change password: '******'userpassword', 'password2') log.fatal('Incorrectly able to to set password to previous password2.') log.fatal('password history: ' + str(user.get_attr_vals('passwordhistory'))) assert False except ldap.CONSTRAINT_VIOLATION: log.info('Password change correctly rejected') except ldap.LDAPError as e: log.fatal('Failed to attempt to change password: '******'userpassword', 'password3') log.fatal('Incorrectly able to to set password to previous password3.') log.fatal('password history: ' + str(user.get_attr_vals('passwordhistory'))) assert False except ldap.CONSTRAINT_VIOLATION: log.info('Password change correctly rejected') except ldap.LDAPError as e: log.fatal('Failed to attempt to change password: '******'userpassword', 'password-reset') time.sleep(1) # Try and change the password to the previous password before the reset try: user.rebind('password-reset') user.set('userpassword', 'password4') log.fatal('Incorrectly able to to set password to previous password4.') log.fatal('password history: ' + str(user.get_attr_vals('passwordhistory'))) assert False except ldap.CONSTRAINT_VIOLATION: log.info('Password change correctly rejected') except ldap.LDAPError as e: log.fatal('Failed to attempt to change password: '******'passwordInHistory', '0') log.info('Configured passwordInHistory to 0.') except ldap.LDAPError as e: log.fatal( 'Failed to configure password policy (passwordInHistory to 0): ' + str(e)) assert False time.sleep(1) # Verify the older passwords in the entry (passwordhistory) are ignored user.rebind('password-reset') user.set('userpassword', 'password4') time.sleep(.5) try: user.set('userpassword', 'password4') log.fatal( 'Incorrectly able to to set password to current password4.') log.fatal('password history: ' + str(user.get_attr_vals('passwordhistory'))) assert False except ldap.CONSTRAINT_VIOLATION: log.info('Password change correctly rejected') except ldap.LDAPError as e: log.fatal('Failed to attempt to change password: '******'userpassword', 'password5') # # Set the history count back to a positive value and make sure things still work # as expected # dm = DirectoryManager(topology_st.standalone) dm.rebind() try: topology_st.standalone.config.replace('passwordInHistory', '2') log.info('Configured passwordInHistory to 2.') except ldap.LDAPError as e: log.fatal( 'Failed to configure password policy (passwordInHistory to 2): ' + str(e)) assert False time.sleep(1) try: user.rebind('password5') user.set('userpassword', 'password5') log.fatal('Incorrectly able to to set password to current password5.') log.fatal('password history: ' + str(user.get_attr_vals('passwordhistory'))) assert False except ldap.CONSTRAINT_VIOLATION: log.info('Password change correctly rejected') except ldap.LDAPError as e: log.fatal('Failed to attempt to change password: '******'userpassword', 'password1') except ldap.LDAPError as e: log.fatal('Failed to attempt to change password: '******'password history: ' + str(user.get_attr_vals('passwordhistory'))) assert False # Done log.info('Test suite PASSED.')
def test_rootdn_access_specific_time(topology_st, rootdn_setup, rootdn_cleanup, timeout=5): """Test binding inside and outside of a specific time :id: a0ef30e5-538b-46fa-9762-01a4435a15e8 :setup: Standalone instance, rootdn plugin set up :steps: 1. Get the current time, and bump it ahead twohours 2. Bind as Root DN 3. Set config to allow the entire day 4. Bind as Root DN 5. Cleanup :expectedresults: 1. Success 2. Should fail 3. Success 4. Success 5. Success """ log.info('Running test_rootdn_access_specific_time...') dm = DirectoryManager(topology_st.standalone) # Get the current time, and bump it ahead twohours current_hour = time.strftime("%H") if int(current_hour) > 12: open_time = '0200' close_time = '0400' else: open_time = '1600' close_time = '1800' assert plugin.replace_many(('rootdn-open-time', open_time), ('rootdn-close-time', close_time)) attr_updated = 0 for i in range(0, timeout): if (plugin.get_attr_val_utf8('rootdn-open-time') == open_time) and ( plugin.get_attr_val_utf8('rootdn-close-time') == close_time): attr_updated = 1 break else: time.sleep(.5) if not attr_updated: raise Exception( "rootdn-open-time and rootdn-close-time were not updated") # Bind as Root DN - should fail for i in range(0, timeout): try: dm.bind() except ldap.UNWILLING_TO_PERFORM: break else: time.sleep(.5) # Set config to allow the entire day open_time = '0000' close_time = '2359' assert plugin.replace_many(('rootdn-open-time', open_time), ('rootdn-close-time', close_time)) attr_updated = 0 for i in range(0, timeout): if (plugin.get_attr_val_utf8('rootdn-open-time') == open_time) and ( plugin.get_attr_val_utf8('rootdn-close-time') == close_time): attr_updated = 1 break else: time.sleep(.5) if not attr_updated: raise Exception( "rootdn-open-time and rootdn-close-time were not updated") # Bind as Root DN - should succeed for i in range(0, timeout): try: dm.bind() break except: time.sleep(.5) # Cleanup - undo the changes we made so the next test has a clean slate assert plugin.apply_mods([(ldap.MOD_DELETE, 'rootdn-open-time'), (ldap.MOD_DELETE, 'rootdn-close-time')])
def test_rootdn_access_day_of_week(topology_st, rootdn_setup, rootdn_cleanup, timeout=5): """Test the days of week feature :id: a0ef30e5-538b-46fa-9762-01a4435a15e1 :setup: Standalone instance, rootdn plugin set up :steps: 1. Set the deny days 2. Bind as Root DN 3. Set the allow days 4. Bind as Root DN :expectedresults: 1. Success 2. Should fail 3. Success 4. Success """ log.info('Running test_rootdn_access_day_of_week...') dm = DirectoryManager(topology_st.standalone) days = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat') day = int(time.strftime("%w", time.gmtime())) if day == 6: # Handle the roll over from Saturday into Sunday deny_days = days[1] + ', ' + days[2] allow_days = days[6] + ',' + days[0] elif day > 3: deny_days = days[0] + ', ' + days[1] allow_days = days[day] + ',' + days[day - 1] else: deny_days = days[4] + ',' + days[5] allow_days = days[day] + ',' + days[day + 1] log.info('Today: ' + days[day]) log.info('Allowed days: ' + allow_days) log.info('Deny days: ' + deny_days) # Set the deny days plugin.set_days_allowed(deny_days) attr_updated = 0 for i in range(0, timeout): if (str(plugin.get_days_allowed()) == deny_days): attr_updated = 1 break else: time.sleep(.5) if not attr_updated: raise Exception("rootdn-days-allowed was not updated") # Bind as Root DN - should fail for i in range(0, timeout): try: dm.bind() except ldap.UNWILLING_TO_PERFORM: break else: time.sleep(.5) # Set the allow days plugin.set_days_allowed(allow_days) attr_updated = 0 for i in range(0, timeout): if (str(plugin.get_days_allowed()) == allow_days): attr_updated = 1 break else: time.sleep(.5) if not attr_updated: raise Exception("rootdn-days-allowed was not updated") # Bind as Root DN - should succeed for i in range(0, timeout): try: dm.bind() break except: time.sleep(.5)