pythonsslactive-directorypython-ldap

Python+LDAP+SSL


Good day.

In advance, I apologize for my English, my national forums and resources did not help.

I am making a script that either changes or creates a user's password in AD

After studying the issue, it became clear that

  1. Password to assign or change can only establish an encrypted connection to the server
  2. Sending the password is only necessary for the encoding utf-16-le

In general there is no problem with the second, but the first has the following problem:

$ python ldap-test-starttls.py 
Traceback (most recent call last):
  File "ldap-test-starttls.py", line 9, in <module>
    l.simple_bind_s( "cn=admin,ou=users,dc=test,dc=ru", "password" )
  File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 206, in simple_bind_s
    msgid = self.simple_bind(who,cred,serverctrls,clientctrls)
  File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 200, in simple_bind
    return    self._ldap_call(self._l.simple_bind,who,cred,EncodeControlTuples(serverctrls),EncodeControlTuples(clientctrls))
  File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 96, in _ldap_call
    result = func(*args,**kwargs)
 ldap.SERVER_DOWN: {'info': 'A TLS packet with unexpected length was received.', 'desc': "Can't contact LDAP server"}

Script code

import ldap
host = 'ldaps://ldap:636'
l = ldap.initialize(host)
l.set_option( ldap.OPT_X_TLS_DEMAND, True )
l.set_option( ldap.OPT_DEBUG_LEVEL, 255 )
username = 'someUser'
new_pass = 'ne$wP4assw0rd3!'
new_password = ('"%s"' % new_pass).encode("utf-16-le")
l.simple_bind_s( "cn=admin,ou=users,dc=test,dc=ru", "password" )
mod_attrs = [(ldap.MOD_REPLACE, 'unicodePwd', new_password)],[( ldap.MOD_REPLACE, 'unicodePwd', new_password)]
l.modify_s('CN=%s,dc=users,dc=test,dc=ru' % username, mod_attrs)
l.unbind_s()
print "Successfully changed password."

Chances are someone has already solved a similar problem. Yes, the script is running on CentOS and using py32win is not possible.


Solution

  • After looking into it more I was able to come up with a solution:

    ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
    l = ldap.initialize("ldaps://ldap:636")
    l.set_option(ldap.OPT_REFERRALS, 0)
    l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
    l.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND)
    l.set_option(ldap.OPT_X_TLS_DEMAND, True)
    l.set_option(ldap.OPT_DEBUG_LEVEL, 255)
    l.simple_bind_s("admin@tester.com", "password")