6

Whenever I try to change someone's password via ldap3 library I get the following error:

{'type': 'modifyResponse', 'result': 53, 'message': '0000001F: SvcErr: DSID-031A12D2, problem 5003 (WILL_NOT_PERFORM), data 0\n\x00', 'referrals': None, 'description': 'unwillingToPerform', 'dn': ''}

This error usually occurs because of the two conditions: either user is trying to modify the password through the unencrypted connection or the password is being sent with the incorrect encoding. My SSL connection is fine (at least it seems to be):

print(connection)
>>> ldaps://DC1.DOMAIN.LOCAL:636 - ssl - user: DOMAIN\admin - not lazy - bound - open - <local: 172.16.10.2:49230 - remote: 172.16.10.254:636> - tls not started - listening - SyncStrategy - internal decoder

I tried to encode the string I'm trying send to the LDAP server, but .encode('utf-16le') didn't do the trick. Any other workarounds?

I have a test domain environment with Windows Server 2012 R2 as a domain controller, and the code I'm trying to change the password with is present below.

import ssl
from ldap3 import *

tls_configuration = Tls(validate=ssl.CERT_REQUIRED, version=ssl.PROTOCOL_TLSv1_2)
s = Server('DC1.domain.local', get_info=ALL, use_ssl=True, tls=tls_configuration)
password = 'mypasswordhere'
c = Connection(s, user="DOMAIN\\admin", password=password)
c.open()
c.bind()

user = "CN=Dummy Dumass,OU=Automatically Generated,OU=Staff,OU=RU,DC=DOMAIN,DC=LOCAL"

c.modify(user, {
    'unicodePwd': [(MODIFY_REPLACE, ['New12345'])]
})

print(c.result)
c.unbind()
John Doe
  • 75
  • 1
  • 4

3 Answers3

8

ldap3 contains a specific method for changing AD password, use the following code instead of c.modify():

c.extend.microsoft.modify_password(user, new_password)

yedpodtrzitko
  • 9,035
  • 2
  • 40
  • 42
cannatag
  • 1,528
  • 11
  • 17
  • password gets properly quoted and utf-16le encoded. – cannatag Jul 03 '16 at 15:27
  • Exactly what i was looking for! That's unusual I didn't find this function when I was skimming through documentation and forum topics I found on Google, but anyways, it worked like a charm, thanks you! – John Doe Jul 03 '16 at 17:50
  • cannatag is correct and I'm just going to add a related note that may help someone else. You will also get this error when trying to enable a user if you haven't set their password yet. If you try to set userAccountControl to 512 for instance, you'll receive the same error. Be sure to call extend.microsoft.modify_password first. – Matt Jan 11 '17 at 20:20
  • The result returned {'result': 0, 'description': 'success', 'dn': '', 'message': '', 'referrals': No ne, 'type': 'modifyResponse'}. But the password is not changed in Active Directory. – Shyamkkhadka Dec 16 '22 at 05:31
1

This code is working with Windows 2012 R2 AD:

pip install ldap

#!/usr/bin/python

import ldap3

SERVER='127.0.0.1'
BASEDN="DC=domain,DC=com"
USER="test-ms-ad@domain.com"
CURREENTPWD="current_password"
NEWPWD="new_password"

SEARCHFILTER='(&(|(userPrincipalName='+USER+')(samaccountname='+USER+')(mail='+USER+'))(objectClass=person))'

USER_DN=""

ldap_server = ldap3.Server(SERVER, get_info=ldap3.ALL)
conn = ldap3.Connection(ldap_server, USER, CURREENTPWD, auto_bind=True)
conn.start_tls()

print conn

conn.search(search_base = BASEDN,
         search_filter = SEARCHFILTER,
         search_scope = ldap3.SUBTREE,
         attributes = ['cn', 'givenName'],
         paged_size = 5)

for entry in conn.response:
    if entry.get("dn") and entry.get("attributes"):
        if entry.get("attributes").get("cn"):
            USER_DN=entry.get("dn")

print USER_DN
print ldap3.extend.microsoft.modifyPassword.ad_modify_password(conn, USER_DN, NEWPWD, CURREENTPWD,  controls=None)
Tamas Tobi
  • 76
  • 3
  • The result returned {'result': 0, 'description': 'success', 'dn': '', 'message': '', 'referrals': No ne, 'type': 'modifyResponse'}. But the password is not changed in Active Directory. – Shyamkkhadka Dec 16 '22 at 05:32
1

The mentioned code is working for me, but changing password is only possible while using ssl. Change the server definition line as below:

ldap_server = ldap3.Server(SERVER, get_info=ldap3.ALL, use_ssl=True)
elcortegano
  • 2,444
  • 11
  • 40
  • 58
Hamed
  • 61
  • 4