Closed sebastianRudolf closed 4 years ago
"Connection reset by peer" means that the LDAP server unexpectedly slammed down the TCP connection.
This feels like a networking issue, or a configuration issue on the LDAP server.
On Fri, 7 Apr 2017 at 14:09 sebastianRudolf notifications@github.com wrote:
Hi
I have developed a Django app for the University of Cape Town and I am currently trying to hook it up with its Active Directory service.
I have tested python-ldap with Python 2.7.12 (default, Nov 19 2016, 06:48:10)
import ldap conn = ldap.initialize('ldap://') conn = ldap.initialize('ldap://137.158.157.86') conn.protocol_version = 3 conn.set_option(ldap.OPT_REFERRALS, 0) conn.simple_bind_s('01421894@wf.uct.ac.za','password') (97, [], 1, [])
which seems to work fine.
I have installed django-python3-ldap as outlined in the README and put the following lines in ./myapp/settings.py (Django 1.10)
AUTHENTICATION_BACKENDS = [ 'django_python3_ldap.auth.LDAPBackend', 'django.contrib.auth.backends.ModelBackend', ] LDAP_AUTH_URL = "ldap://msldap.uct.ac.za:636" LDAP_AUTH_USE_TLS = False LDAP_AUTH_SEARCH_BASE = "OU=UCT,DC=wf,DC=uct,DC=ac,DC=za" LDAP_AUTH_OBJECT_CLASS = "inetOrgPerson" LDAP_AUTH_USER_FIELDS = { "username": "uid", "first_name": "givenName", "last_name": "sn", "email": "mail", } LDAP_AUTH_USER_LOOKUP_FIELDS = ("username",) LDAP_AUTH_CLEAN_USER_DATA = "django_python3_ldap.utils.clean_user_data" LDAP_AUTH_SYNC_USER_RELATIONS = "django_python3_ldap.utils.sync_user_relations" LDAP_AUTH_FORMAT_SEARCH_FILTERS = "django_python3_ldap.utils.format_search_filters" LDAP_AUTH_FORMAT_USERNAME = "django_python3_ldap.utils.format_username_active_directory" LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = "wf.uct.ac.za" LDAP_AUTH_CONNECTION_USERNAME = None LDAP_AUTH_CONNECTION_PASSWORD = None
Executing the test command: python manage.py ldap_sync_users produces the following which seems like no users have been found:
LDAP connect failed: error receiving data: [Errno 104] Connection reset by peer Traceback (most recent call last): File "manage.py", line 22, in execute_from_command_line(sys.argv) File "/usr/local/lib/python2.7/dist-packages/django/core/management/init.py", line 367, in execute_from_command_line utility.execute() File "/usr/local/lib/python2.7/dist-packages/django/core/management/init.py", line 359, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 294, in run_from_argv self.execute(*args, cmd_options) File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 345, in execute output = self.handle(*args, *options) File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py", line 185, in inner return func(args, kwargs) File "/usr/local/lib/python2.7/dist-packages/django_python3_ldap/management/commands/ldap_sync_users.py", line 19, in handle for user in connection.iter_users(): AttributeError: 'NoneType' object has no attribute 'iter_users'
I suspect it might be something quite trivial. Please advise.
Sebastian
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/etianen/django-python3-ldap/issues/72, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJFCHphdClHr919uLAFvEH6iftUk_sUks5rtjV6gaJpZM4M24DP .
Thanks for your response.
I would agree with you. When look at the Python script in question "ldap_sync_users.py"
def handle(self, *args, **kwargs):
verbosity = int(kwargs.get("verbosity", 1))
with ldap.connection(
username=settings.LDAP_AUTH_CONNECTION_USERNAME,
password=settings.LDAP_AUTH_CONNECTION_PASSWORD,
) as connection:
for user in connection.iter_users():
if verbosity >= 1:
self.stdout.write("Synced {user}".format(
user=user,
))
The 'connection' object in line 7 is NoneType which indicates that the binding did not happen I guess.
Is there anything very obviously wrong of the LDAP settings in myapp/settings.py (see above in my first post)? The reason why I am asking is that the manual binding using my above test in the python shell above was successful.
I've pushed a fix to master to turn the NoneType error into something a bit nicer. But that wasn't actually your problem! :P
Some items in your settings that you might want to investigate:
On Tue, 11 Apr 2017 at 12:26 sebastianRudolf notifications@github.com wrote:
Thanks for your response.
I would agree with you. When look at the Python script in question "ldap_sync_users.py"
def handle(self, *args, **kwargs): verbosity = int(kwargs.get("verbosity", 1)) with ldap.connection( username=settings.LDAP_AUTH_CONNECTION_USERNAME, password=settings.LDAP_AUTH_CONNECTION_PASSWORD, ) as connection: for user in connection.iter_users(): if verbosity >= 1: self.stdout.write("Synced {user}".format( user=user, ))
The 'connection' object in line 7 is NoneType which indicates that the binding did not happen I guess.
Is there anything very obviously wrong of the LDAP settings in myapp/settings.py (see above in my first post)? The reason why I am asking is that the manual binding using my above test in the python shell above was successful.
— You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/etianen/django-python3-ldap/issues/72#issuecomment-293228419, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJFCAGW2naLZdmcHTJO_RE-0NnbKeYsks5ru2NYgaJpZM4M24DP .
I have already tried LDAP_AUTH_URL = "ldap://137.158.157.86" which did not work (it did work for the manual binding test though).
Actually the ldap username format is XXXXXXXX@wf.uct.ac.za indeed, for all staff at UCT. The login to my server where I am running my Django app is via the same Active Directory service (my username is 01421894), as it is a UCT server machine.
What other username format could I use?
There are several ways to format an AD username. Try using this line instead of the one you had:
conn.simple_bind_s('wf.uct.ac.za 01421894@wf.uct.ac.za\01421894 01421894@wf.uct.ac.za','password')
(The domain first, separated by the username by a backslash)
On Tue, 11 Apr 2017 at 14:20 sebastianRudolf notifications@github.com wrote:
I have already tried LDAP_AUTH_URL = "ldap://137.158.157.86" which did not work (it did work for the manual binding test though).
Actually the ldap username format is XXXXXXXX@wf.uct.ac.za indeed, for all staff at UCT. The login to my server where I am running my Django app is via the same Active Directory service (my username is 01421894), as it is a UCT server machine.
What other username format could I use?
— You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/etianen/django-python3-ldap/issues/72#issuecomment-293259854, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJFCN044ydNx4BVRumxJOtACMADFL_xks5ru34UgaJpZM4M24DP .
Hm, if I do an exact copy-paste of your formatting suggestion, i.e.
conn.simple_bind_s('wf.uct.ac.za 01421894@wf.uct.ac.za\01421894 01421894@wf.uct.ac.za','password')
this does not work.
I also tried (in case I misunderstood you):
conn2.simple_bind_s('wf.uct.ac.za\01421894','password')
which did not work either.
Try your second one, with two backslashes, as you have to escape backslashes in Python strings. On Tue, 11 Apr 2017 at 18:43, sebastianRudolf notifications@github.com wrote:
Hm, if I do an exact copy-paste of your formatting suggesting, i.e.
conn.simple_bind_s('wf.uct.ac.za 01421894@wf.uct.ac.za\01421894 01421894@wf.uct.ac.za','password')
this does not work.
I also tried (in case I misunderstood you):
conn2.simple_bind_s('wf.uct.ac.za\01421894','password')
which did not work either.
— You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/etianen/django-python3-ldap/issues/72#issuecomment-293341553, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJFCLjp8_Rj2-HqT4-ksgYs7FOQU9_Mks5ru7vEgaJpZM4M24DP .
I've just added support for the email-style usernames:
https://github.com/etianen/django-python3-ldap#microsoft-active-directory-support
Upgrade to the master branch, then use these settings:
AUTHENTICATION_BACKENDS = [
'django_python3_ldap.auth.LDAPBackend',
'django.contrib.auth.backends.ModelBackend',
]
LDAP_AUTH_URL = "ldap://msldap.uct.ac.za:636"
LDAP_AUTH_USE_TLS = False
LDAP_AUTH_SEARCH_BASE = "OU=UCT,DC=wf,DC=uct,DC=ac,DC=za"
LDAP_AUTH_OBJECT_CLASS = "inetOrgPerson"
LDAP_AUTH_USER_FIELDS = {
"username": "uid",
"first_name": "givenName",
"last_name": "sn",
"email": "mail",
}
LDAP_AUTH_USER_LOOKUP_FIELDS = ("username",)
LDAP_AUTH_CLEAN_USER_DATA = "django_python3_ldap.utils.clean_user_data"
LDAP_AUTH_SYNC_USER_RELATIONS = "django_python3_ldap.utils.sync_user_relations"
LDAP_AUTH_FORMAT_SEARCH_FILTERS = "django_python3_ldap.utils.format_search_filters"
LDAP_AUTH_FORMAT_USERNAME = "django_python3_ldap.utils.format_username_active_directory_principal"
LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = "wf.uct.ac.za"
LDAP_AUTH_CONNECTION_USERNAME = None
LDAP_AUTH_CONNECTION_PASSWORD = None
hi Noting your changes, I have done an update: pip install -U django-python3-ldap
Then I tried to establish a simple binding as instructed by you but that did not work:
Python 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609] on linux2 Type "help", "copyright", "credits" or "license" for more information.
import ldap conn = ldap.initialize('ldap://') conn = ldap.initialize('ldap://msldap.uct.ac.za') conn.protocol_version = 3 conn.set_option(ldap.OPT_REFERRALS, 0) conn.simple_bind_s('wf.uct.ac.za\01421894','password') Traceback (most recent call last): File "
", line 1, in File "/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py", line 223, in simple_bind_s resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all=1,timeout=self.timeout) File "/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py", line 514, in result3 resp_ctrl_classes=resp_ctrl_classes File "/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py", line 521, in result4 ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop) File "/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py", line 106, in _ldap_call result = func(*args,**kwargs) ldap.INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C0903A8, comment: AcceptSecurityContext error, data 52e, v1db1', 'desc': 'Invalid credentials'} conn.simple_bind_s('01421894@wf.uct.ac.za','password') (97, [], 2, [])
Hmm, sorry, that's not what I meant.
For the simple binding, you should use:
import ldap
conn = ldap.initialize('ldap://')
conn = ldap.initialize('ldap://msldap.uct.ac.za:636')
conn.protocol_version = 3
conn.set_option(ldap.OPT_REFERRALS, 0)
conn.simple_bind_s('01421894@wf.uct.ac.za','password')
This maps to the following Django settings:
AUTHENTICATION_BACKENDS = [
'django_python3_ldap.auth.LDAPBackend',
'django.contrib.auth.backends.ModelBackend',
]
LDAP_AUTH_URL = "ldap://msldap.uct.ac.za:636"
LDAP_AUTH_USE_TLS = False
LDAP_AUTH_SEARCH_BASE = "OU=UCT,DC=wf,DC=uct,DC=ac,DC=za"
LDAP_AUTH_OBJECT_CLASS = "inetOrgPerson"
LDAP_AUTH_USER_FIELDS = {
"username": "uid",
"first_name": "givenName",
"last_name": "sn",
"email": "mail",
}
LDAP_AUTH_USER_LOOKUP_FIELDS = ("username",)
LDAP_AUTH_CLEAN_USER_DATA = "django_python3_ldap.utils.clean_user_data"
LDAP_AUTH_SYNC_USER_RELATIONS = "django_python3_ldap.utils.sync_user_relations"
LDAP_AUTH_FORMAT_SEARCH_FILTERS = "django_python3_ldap.utils.format_search_filters"
LDAP_AUTH_FORMAT_USERNAME = "django_python3_ldap.utils.format_username_active_directory_principal"
LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = "wf.uct.ac.za"
LDAP_AUTH_CONNECTION_USERNAME = None
LDAP_AUTH_CONNECTION_PASSWORD = None
I also did the 2 suggested changes in 'myapp/settings.py'
LDAP_AUTH_URL = "ldap://msldap.uct.ac.za:636" LDAP_AUTH_FORMAT_USERNAME = "django_python3_ldap.utils.format_username_active_directory_principal"
(the remaining settings are unchanged).
Executing the test script I get the following:
01421894$:/var/www/seat$ python manage.py ldap_sync_users LDAP connect failed: error receiving data: [Errno 104] Connection reset by peer CommandError: Could not connect to LDAP server
I wonder what the difference is between the Django config, and the raw python script?
Does this work (no protocol version):
import ldap
conn = ldap.initialize('ldap://')
conn = ldap.initialize('ldap://msldap.uct.ac.za:636')
# conn.protocol_version = 3
conn.set_option(ldap.OPT_REFERRALS, 0)
conn.simple_bind_s('01421894@wf.uct.ac.za','password')
It looks like our AD server is down now. I have contacted our IT department to check.
conn2 = ldap.initialize('ldap://') conn2 = ldap.initialize('ldap://msldap.uct.ac.za:636') conn2.set_option(ldap.OPT_REFERRALS, 0) conn2.simple_bind_s('01421894@wf.uct.ac.za','password') Traceback (most recent call last): File "
", line 1, in File "/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py", line 223, in simple_bind_s resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all=1,timeout=self.timeout) File "/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py", line 514, in result3 resp_ctrl_classes=resp_ctrl_classes File "/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py", line 521, in result4 ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop) File "/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py", line 106, in _ldap_call result = func(*args,**kwargs) ldap.SERVER_DOWN: {'desc': "Can't contact LDAP server"}
I checked with UCT's IT department, the AD server msldap.uct.ac.za is definitely not down.
I think, since updated the django-python3-ldap module, the simple manual binding does not work anymore:
$ python Python 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609] on linux2 Type "help", "copyright", "credits" or "license" for more information.
import ldap conn = ldap.initialize('ldap://') conn = ldap.initialize('ldap://msldap.uct.ac.za:636') conn.protocol_version = 3 conn.set_option(ldap.OPT_REFERRALS, 0) conn.simple_bind_s('01421894@wf.uct.ac.za','password') Traceback (most recent call last): File "
", line 1, in File "/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py", line 223, in simple_bind_s resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all=1,timeout=self.timeout) File "/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py", line 514, in result3 resp_ctrl_classes=resp_ctrl_classes File "/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py", line 521, in result4 ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop) File "/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py", line 106, in _ldap_call result = func(*args,**kwargs) ldap.SERVER_DOWN: {'desc': "Can't contact LDAP server"}
Hmm.
If you can get it working with the simple manual binding, I can tell you how to link that up to django-python3-ldap. But without that, I'm afraid I'm stuck.
Try connecting to the LDAP server using telnet, just to make sure that the django machine can connect to it?
By accident, I left the port number away and it worked for the simple manual binding:
$ python Python 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609] on linux2 Type "help", "copyright", "credits" or "license" for more information.
import ldap conn = ldap.initialize('ldap://' + 'msldap.uct.ac.za') conn.protocol_version = 3 conn.simple_bind_s('01421894@wf.uct.ac.za','password') (97, [], 1, [])
I also tried again the test script of your module removing in myapp/settings.py the port number and I got the following output:
python manage.py ldap_sync_users LDAP connect failed: LDAPOperationsErrorResult - 1 - operationsError - None - 000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db1 - searchResDone - None CommandError: Could not connect to LDAP server
Perhaps, I need to specify a different port number?
By the looks of things, your simple manual binding is using the python-ldap package, rather than ldap3?
It might be best if you debug this using the ldap3 package, since that's what django-python3-ldap uses. Try getting something like this to work:
https://gist.github.com/etianen/34b2567bc957acaf7ac4d854d6f82f27
Once you've got that working, translating it into Django settings should be easy.
On Wed, 19 Apr 2017 at 15:40 sebastianRudolf notifications@github.com wrote:
By accident, I left the port number away and it worked for the simple manual binding:
$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609] on linux2 Type "help", "copyright", "credits" or "license" for more information.
import ldap conn = ldap.initialize('ldap://' + 'msldap.uct.ac.za') conn.protocol_version = 3
conn.simple_bind_s('01421894@wf.uct.ac.za','password') (97, [], 1, [])
I also tried again the test script of your module removing in myapp/settings.py the port number and I got the following output:
python manage.py ldap_sync_users LDAP connect failed: LDAPOperationsErrorResult - 1 - operationsError - None - 000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db1 - searchResDone - None
CommandError: Could not connect to LDAP server
Perhaps, I need to specify a different port number?
— You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/etianen/django-python3-ldap/issues/72#issuecomment-295293562, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJFCBDGhkgnFtXvHhNFq7sKQnmFkbFEks5rxhzjgaJpZM4M24DP .
True, thanks for pointing this out.
I checked out the script where you provided the link and it seems to work with ldap3:
$ python Python 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609] on linux2 Type "help", "copyright", "credits" or "license" for more information.
import ldap3 ldap3.Connection( ... ldap3.Server( ... "ldap://msldap.uct.ac.za", ... allowed_referral_hosts=[("", True)], ... ), ... user="01421894@wf.uct.ac.za", ... password="password", ... auto_bind=ldap3.AUTO_BIND_NO_TLS, ... raise_exceptions=True, ... ) Connection(server=Server(host='msldap.uct.ac.za', port=389, use_ssl=False, allowed_referral_hosts=[('', True)], get_info='SCHEMA'), user='01421894@wf.uct.ac.za', password='password', auto_bind='NO_TLS', version=3, authentication='SIMPLE', client_strategy='SYNC', auto_referrals=True, check_names=True, read_only=False, lazy=False, raise_exceptions=True, fast_decoder=True, auto_range=True, return_empty_attributes=True)
Based on that, I think your settings should be:
LDAP_AUTH_URL = "ldap://msldap.uct.ac.za"
LDAP_AUTH_FORMAT_USERNAME = "django_python3_ldap.utils.format_username_active_directory_principal"
LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = "wf.uct.ac.za""
This is what I am already using but it gives me the following error:
/var/www/seat$ python manage.py ldap_sync_users LDAP connect failed: LDAPOperationsErrorResult - 1 - operationsError - None - 000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db1 - searchResDone - None CommandError: Could not connect to LDAP server
By the way, my Django installation makes use of Python 2.7.12 (not Python3). Also, does your test script require special access rights to the MyApp installation directory (/var/www/seat)? Currently user and group is 'www-data'.
Below LDAP relevant content of settings.py:
AUTHENTICATION_BACKENDS = [ 'django_python3_ldap.auth.LDAPBackend', 'django.contrib.auth.backends.ModelBackend', ] LDAP_AUTH_URL = "ldap://msldap.uct.ac.za" LDAP_AUTH_USE_TLS = False LDAP_AUTH_SEARCH_BASE = "OU=UCT,DC=wf,DC=uct,DC=ac,DC=za" LDAP_AUTH_OBJECT_CLASS = "inetOrgPerson" LDAP_AUTH_USER_FIELDS = { "username": "uid", "first_name": "givenName", "last_name": "sn", "email": "mail", } LDAP_AUTH_USER_LOOKUP_FIELDS = ("username",) LDAP_AUTH_CLEAN_USER_DATA = "django_python3_ldap.utils.clean_user_data" LDAP_AUTH_SYNC_USER_RELATIONS = "django_python3_ldap.utils.sync_user_relations" LDAP_AUTH_FORMAT_SEARCH_FILTERS = "django_python3_ldap.utils.format_search_filters" LDAP_AUTH_FORMAT_USERNAME = "django_python3_ldap.utils.format_username_active_directory_principal" LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = "wf.uct.ac.za" LDAP_AUTH_CONNECTION_USERNAME = None LDAP_AUTH_CONNECTION_PASSWORD = None LOGGING = { "version": 1, "disable_existing_loggers": False, "handlers": { "console": { "class": "logging.StreamHandler", }, }, "loggers": { "django_python3_ldap": { "handlers": ["console"], "level": "INFO", }, }, }
Aha!
LDAP_AUTH_CONNECTION_USERNAME = "01421894"
LDAP_AUTH_CONNECTION_PASSWORD = "password"
Looks like your server isn't set up for anonymous queries, so you need to hardcode a username and password in the config file.
OK, I set username and password in the myapp/settings.py as suggest and I get the following error:
$ python manage.py ldap_sync_users
Traceback (most recent call last):
File "manage.py", line 22, in
You need to use the latest master branch.
On Thu, 27 Apr 2017 at 17:02 sebastianRudolf notifications@github.com wrote:
OK, I set username and password in the myapp/settings.py as suggest and I get the following error:
$ python manage.py ldap_sync_users
Traceback (most recent call last): File "manage.py", line 22, in execute_from_command_line(sys.argv)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/init.py", line 363, in execute_from_command_line utility.execute() File "/usr/local/lib/python2.7/dist-packages/django/core/management/init.py", line 355, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 283, in run_from_argv self.execute(*args, **cmd_options) File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 330, in execute
output = self.handle(*args, *options) File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py", line 185, in inner return func(args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django_python3_ldap/management/commands/ldap_sync_users.py", line 17, in handle password=settings.LDAP_AUTH_CONNECTION_PASSWORD, File "/usr/lib/python2.7/contextlib.py", line 17, in enter return self.gen.next() File "/usr/local/lib/python2.7/dist-packages/django_python3_ldap/ldap.py", line 132, in connection username = import_func(settings.LDAP_AUTH_FORMAT_USERNAME)(kwargs) File "/usr/local/lib/python2.7/dist-packages/django_python3_ldap/utils.py", line 19, in import_func return import_string(func) File "/usr/local/lib/python2.7/dist-packages/django/utils/module_loading.py", line 27, in import_string six.reraise(ImportError, ImportError(msg), sys.exc_info()[2]) File "/usr/local/lib/python2.7/dist-packages/django/utils/module_loading.py", line 23, in import_string return getattr(module, class_name) ImportError: Module "django_python3_ldap.utils" does not define a "format_username_active_directory_principal" attribute/class
— You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/etianen/django-python3-ldap/issues/72#issuecomment-297759003, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJFCFIaNNPJ_AXD4XtkKsZgMehti6-Oks5r0Lv1gaJpZM4M24DP .
I had this exact same issue. Although I was not using django-python3-ldap, I was using Django, Python 3 and python-ldap. I thought I would share my experience here for posterity.
I work for an international company (although, coincidentally, I am also based in Cape Town). I built an internal application to authenticate against our Active Directory server. No matter what I tried, the first authentication attempt always failed with "connection reset by peer". The second attempt would work.
I eventually figured out that the problem lay with the F5 load balancer the company uses. If I bypassed the load balancer, I could successfully authenticate my Django application against Active Directory on the first attempt. There was no problem with the code: it was a network issue.
Our IT department is still investigating why the load balancer causes this issue. In the meantime, I have implemented a simple function for AUTH_LDAP_SERVER_URI which selects a random authentication server to use (a thread probes the servers and marks them as down if they don't respond).
I hope that, if someone else has the misfortune to encounter this issue, that this answer helps them.
Thanks for the report! This is going to make somebody's day, someday!
Hi
I have developed a Django app for the University of Cape Town and I am currently trying to hook it up with its Active Directory service.
I have tested python-ldap with Python 2.7.12 (default, Nov 19 2016, 06:48:10)
which seems to work fine.
I have installed django-python3-ldap as outlined in the README and put the following lines in ./myapp/settings.py (Django 1.10)
AUTHENTICATION_BACKENDS = [ 'django_python3_ldap.auth.LDAPBackend', 'django.contrib.auth.backends.ModelBackend', ] LDAP_AUTH_URL = "ldap://msldap.uct.ac.za:636" LDAP_AUTH_USE_TLS = False LDAP_AUTH_SEARCH_BASE = "OU=UCT,DC=wf,DC=uct,DC=ac,DC=za" LDAP_AUTH_OBJECT_CLASS = "inetOrgPerson" LDAP_AUTH_USER_FIELDS = { "username": "uid", "first_name": "givenName", "last_name": "sn", "email": "mail", } LDAP_AUTH_USER_LOOKUP_FIELDS = ("username",) LDAP_AUTH_CLEAN_USER_DATA = "django_python3_ldap.utils.clean_user_data" LDAP_AUTH_SYNC_USER_RELATIONS = "django_python3_ldap.utils.sync_user_relations" LDAP_AUTH_FORMAT_SEARCH_FILTERS = "django_python3_ldap.utils.format_search_filters" LDAP_AUTH_FORMAT_USERNAME = "django_python3_ldap.utils.format_username_active_directory" LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = "wf.uct.ac.za" LDAP_AUTH_CONNECTION_USERNAME = None LDAP_AUTH_CONNECTION_PASSWORD = None
Executing the test command: python manage.py ldap_sync_users produces the following which seems like no users have been found:
LDAP connect failed: error receiving data: [Errno 104] Connection reset by peer Traceback (most recent call last): File "manage.py", line 22, in
execute_from_command_line(sys.argv)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/init.py", line 367, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python2.7/dist-packages/django/core/management/init.py", line 359, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 294, in run_from_argv
self.execute(*args, cmd_options)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 345, in execute
output = self.handle(*args, *options)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py", line 185, in inner
return func(args, kwargs)
File "/usr/local/lib/python2.7/dist-packages/django_python3_ldap/management/commands/ldap_sync_users.py", line 19, in handle
for user in connection.iter_users():
AttributeError: 'NoneType' object has no attribute 'iter_users'
I suspect it might be something quite trivial. Please advise.
Sebastian