예제 #1
0
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)
예제 #2
0
    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()
예제 #3
0
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")
예제 #4
0
    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()
예제 #5
0
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))
예제 #6
0
 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
예제 #7
0
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()
예제 #8
0
    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
예제 #10
0
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
예제 #11
0
    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()
예제 #12
0
    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()
예제 #13
0
    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()
예제 #14
0
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.')
예제 #15
0
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')])
예제 #16
0
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)