Changing userPassword in OpenLDAP using ldap3 library
<p>I can't seem to change a users password using the ldap3 python module against an OpenLDAP server. A similar question has been asked <a href="http://stackoverflow.com/questions/37847042/changing-active-directory-user-password-in-python-3-x">before</a> but that's specific to Active Directory.</p>

<p>What I've tried:</p>

<pre><code>from ldap3.extend.standard.modifyPassword import ModifyPassword
from ldap3.utils.hashed import hashed
password = hashed(HASHED_SALTED_SHA, password)
# or..
password = '{SASL}theuser@domain.com'
modify = ModifyPassword(
    connection, user.entry_get_dn(), new_password=password)
resp = modify.send()
print(modify.result)
{'referrals': None, 'result': 0, 'description': 'success', 'type': 'extendedResp', 'message': '', 'responseName': None, 'new_password': None, 'dn': '', 'responseValue': None}
</code></pre>

<p>The description says success, but the password isn't actually changed.</p>

<p>I've also tried to send a modify replace message:</p>

<pre><code>def modify_user_password(self, user, password):
    dn = user.entry_get_dn()
    hashed_password = hashed(HASHED_SALTED_SHA, 'MyStupidPassword')
    changes = {
        'userPassword': [(MODIFY_REPLACE, [hashed_password])]
    }
    logger.debug('dn: ' + dn)
    logger.debug('changes: ' + str(changes))
    success = self.engage_conn.modify(dn, changes=changes)
    if success:
        logger.debug('Changed password for: %s', dn)
        print(self.engage_conn.result)
    else:
        logger.warn('Unable to change password for %s', dn)
        logger.debug(str(self.engage_conn.result))
        raise ValueError('stop')
</code></pre>

<p>The connection is <strong>not</strong> an SSL connection. The answer to the AD question requires that the connection be over SSL. Is this also a requirement for OpenLDAP?</p>

<p>Edit:</p>

<p>After changing the <code>dn</code> to <code>user.entry_get_dn()</code> the code seemed to work about 90% of the time. After running these tests again today it appears that it now works consistently. I'm going to chalk this up to not viewing fresh data in my directory browser.</p>

<p>Changing the password seems to work as described in the docs and shown in the edit of my question above. For future reference, this code seems to work:</p>

<pre><code>from ldap3 import (
    HASHED_SALTED_SHA, MODIFY_REPLACE
)
from ldap3.utils.hashed import hashed

def modify_user_password(self, user, password):
    dn = user.entry_get_dn()
    hashed_password = hashed(HASHED_SALTED_SHA, password)
    changes = {
        'userPassword': [(MODIFY_REPLACE, [hashed_password])]
    }
    success = self.connection.modify(dn, changes=changes)
    if not success:
        print('Unable to change password for %s' % dn)
        print(self.connection.result)
        raise ValueError('Unable to change password')
</code></pre>

<p>To clarify a few things:</p>

<ol>
<li>This is connecting to an OpenLDAP server (with multiple databases)</li>
<li>There is <strong>NO</strong> SSL here. We plan on implementing SSL but this works without it.</li>
</ol>

python python-3.x openldap ldap3