Pergunta

Good day.

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

There was a need in the script that changes (or creates) a user 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. Send the password is only necessary in the encoding utf-16-le

In general there is no problem with the second, but first have a problem with

$ 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 use py32win not possible.

Thanks in advance.

Foi útil?

Solução

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")

Outras dicas

I also think OPT_X_TLS_NEVER will disable TLS,so pls don't use that.

set_option(ldap.OPT_X_TLS_NEWCTX, ldap.OPT_ON): LDAP_OPT_X_TLS_NEWCTX has to be called after calling ldap_set_option() to set the TLS attributes, if it's called prior to setting the attributes (as is the current code) then the TLS attributes are not copied into the new TLS context.

so my solution is

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)
# This must be the last tls setting to create TLS context.
l.set_option(ldap.OPT_X_TLS_NEWCTX, ldap.OPT_ON)
l.simple_bind_s("admin@tester.com","password")

@see python-ldap/issues/55

@see enter link description here

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top