From jcasale at activenetwerx.com Thu Jan 2 15:22:33 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Thu, 2 Jan 2014 14:22:33 +0000 Subject: [python-ldap] SASL + REALM In-Reply-To: <1388413851.30325.YahooMailNeo@web28702.mail.ir2.yahoo.com> References: <1388413851.30325.YahooMailNeo@web28702.mail.ir2.yahoo.com> Message-ID: > I've got a problem using python-ldap with SASL + REALM. I don't have any > clue what's wrong with it and tumbling around in the dark. > Here is my code snippet: > ??? ??? ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, > ldap.OPT_X_TLS_NEVER) > ??? ??? ldap.set_option(ldap.OPT_DEBUG_LEVEL, 4095) > ??????? username = 'ldapadmin-222' > ??? ??? password = 'pass' > ??? ??? realm = 'company' > ??????? l = ldap.initialize('ldaps://ldapsrv.mydomain.local:60000', trace_level=2) > ??????? auth_token = ldap.sasl.sasl( > ???????????? { > ???????????????? ldap.sasl.CB_AUTHNAME:(username), > ???????????????? ldap.sasl.CB_PASS:(password), > ???????????????? ldap.sasl.CB_USER:(username), > ???????????????? ldap.sasl.CB_GETREALM:(realm), > ???????????? }, > ???????????? 'DIGEST-MD5' > ??????? ) > ?? try: > ??????? l.sasl_interactive_bind_s( "", auth_token ) > ?? except ldap.LDAPError, e: > ??????? print e > ?? except ldap.INVALID_CREDENTIALS, e : > ??????? print e > ?? finally: > ??????? l.unbind_s() > > It always fails with > LDAPError - INVALID_CREDENTIALS: {'info': '8009030C: LdapErr: DSID- > 0C0904DC, comment: AcceptSecurityContext error, data 52e, v1db1', 'desc': > 'Invalid credentials'} I'm not an authority here, but I am guessing you're missing some additional options relating to negotiation after initialization, or at least a quick of read of the rfc suggests so. Check out this: http://stackoverflow.com/questions/7716562/pythonldapssl hth, jlc From michael at stroeder.com Thu Jan 2 20:21:15 2014 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Thu, 02 Jan 2014 20:21:15 +0100 Subject: [python-ldap] SASL + REALM In-Reply-To: References: <1388413851.30325.YahooMailNeo@web28702.mail.ir2.yahoo.com> Message-ID: <52C5BC2B.8010507@stroeder.com> Joseph L. Casale wrote: >> I've got a problem using python-ldap with SASL + REALM. I don't have any >> clue what's wrong with it and tumbling around in the dark. >> Here is my code snippet: >> ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, >> ldap.OPT_X_TLS_NEVER) >> ldap.set_option(ldap.OPT_DEBUG_LEVEL, 4095) >> username = 'ldapadmin-222' >> password = 'pass' >> realm = 'company' >> l = ldap.initialize('ldaps://ldapsrv.mydomain.local:60000', trace_level=2) >> auth_token = ldap.sasl.sasl( >> { >> ldap.sasl.CB_AUTHNAME:(username), >> ldap.sasl.CB_PASS:(password), >> ldap.sasl.CB_USER:(username), >> ldap.sasl.CB_GETREALM:(realm), >> }, >> 'DIGEST-MD5' >> ) >> try: >> l.sasl_interactive_bind_s( "", auth_token ) >> except ldap.LDAPError, e: >> print e >> except ldap.INVALID_CREDENTIALS, e : >> print e >> finally: >> l.unbind_s() >> >> It always fails with >> LDAPError - INVALID_CREDENTIALS: {'info': '8009030C: LdapErr: DSID- >> 0C0904DC, comment: AcceptSecurityContext error, data 52e, v1db1', 'desc': >> 'Invalid credentials'} > > I'm not an authority here, but I am guessing you're missing some additional options > relating to negotiation after initialization, or at least a quick of read of the rfc suggests > so. > > Check out this: http://stackoverflow.com/questions/7716562/pythonldapssl Maybe I'm overlooking something but could you please elaborate on why you think this is related? Ciao, Michael. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2398 bytes Desc: S/MIME Cryptographic Signature URL: From jcasale at activenetwerx.com Thu Jan 2 22:41:51 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Thu, 2 Jan 2014 21:41:51 +0000 Subject: [python-ldap] SASL + REALM In-Reply-To: <52C5BC2B.8010507@stroeder.com> References: <1388413851.30325.YahooMailNeo@web28702.mail.ir2.yahoo.com> <4271538df69b4e048e766feedc884f36@exch.activenetwerx.com> <52C5BC2B.8010507@stroeder.com> Message-ID: > Maybe I'm overlooking something but could you please elaborate on why > you > think this is related? His question wasn't but the approach with the options looked correct. Was merely a pointer to code that looked to have a valid flow. From andrius.kulbis at gmail.com Tue Jan 28 10:58:36 2014 From: andrius.kulbis at gmail.com (Andrius Kulbis) Date: Tue, 28 Jan 2014 11:58:36 +0200 Subject: [python-ldap] Password policy account locked scenario Message-ID: <52E77F4C.8080607@gmail.com> Hello, I don't know is it not implemented or I I'm doing something the wrong way. How can I get account locket ppolicy response? I try to bind using the locked acc, but only get INVALID_CREDENTIALS exception Regards, Andrius From michael at stroeder.com Fri Jan 31 18:23:22 2014 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Fri, 31 Jan 2014 18:23:22 +0100 Subject: [python-ldap] ANN: python-ldap 2.4.14 Message-ID: <52EBDC0A.2050600@stroeder.com> Find a new release of python-ldap: http://pypi.python.org/pypi/python-ldap/2.4.14 python-ldap provides an object-oriented API to access LDAP directory servers from Python programs. It mainly wraps the OpenLDAP 2.x libs for that purpose. Additionally it contains modules for other LDAP-related stuff (e.g. processing LDIF, LDAP URLs and LDAPv3 schema). Project's web site: http://www.python-ldap.org/ Ciao, Michael. ---------------------------------------------------------------- Released 2.4.14 2014-01-31 Changes since 2.4.13: Lib/ * Added ldap.controls.openldap.SearchNoOpControl * New method ldap.async.AsyncSearchHandler.afterFirstResult() for doing something right after successfully receiving but before processing first result * Better log data written when invoking ldap.LDAPLock.acquire() and ldap.LDAPLock.release() * LDAPObject and friends now pass `desc' to ldap.LDAPLock() which results in better logging * ldapobject.ReconnectLDAPObject now uses internal class-wide lock for serializing reconnects * Method signature of ReconnectLDAPObject.reconnect() changed to be able to call it with separate retry_max and retry_delay values Modules/ * Added support for retrieving negotiated TLS version/cipher with LDAPObject.get_option() with the help of upcoming OpenLDAP libs From michael at stroeder.com Fri Jan 31 22:48:42 2014 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Fri, 31 Jan 2014 22:48:42 +0100 Subject: [python-ldap] ANN: python-ldap 2.4.14 In-Reply-To: <52EBDC0A.2050600@stroeder.com> References: <52EBDC0A.2050600@stroeder.com> Message-ID: <52EC1A3A.40801@stroeder.com> Michael Str?der wrote: > Find a new release of python-ldap: > > http://pypi.python.org/pypi/python-ldap/2.4.14 BTW: You can find SuSE Linux builds here: https://build.opensuse.org/package/show?package=python-ldap&project=devel%3Alanguages%3Apython Ciao, Michael. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2398 bytes Desc: S/MIME Cryptographic Signature URL: From jcasale at activenetwerx.com Mon Feb 17 16:57:25 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Mon, 17 Feb 2014 15:57:25 +0000 Subject: [python-ldap] Ldif record parsing Message-ID: <7be774691fd340049e625781bb0daa0f@exch.activenetwerx.com> I was writing some unit tests for an app and noticed for delete changetype records with only an dn and no entry records that LDIFParser.parse only hands the parsed data off to handle() if the entry has records. Obviously most of the time this makes sense but as the changetype is local to parse(), it's not available even during other cases where an entry exists. As a result, tests never fully validate. I could simply redefine parse() but I wonder how other people addressed this when writing tests? Thanks, jlc From michael at stroeder.com Mon Feb 17 19:58:13 2014 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Mon, 17 Feb 2014 19:58:13 +0100 Subject: [python-ldap] Ldif record parsing In-Reply-To: <7be774691fd340049e625781bb0daa0f@exch.activenetwerx.com> References: <7be774691fd340049e625781bb0daa0f@exch.activenetwerx.com> Message-ID: <53025BC5.2060201@stroeder.com> Joseph L. Casale wrote: > I was writing some unit tests for an app and noticed for delete changetype records with > only an dn and no entry records that LDIFParser.parse only hands the parsed data off to > handle() if the entry has records. Obviously most of the time this makes sense but as the > changetype is local to parse(), it's not available even during other cases where an entry > exists. As a result, tests never fully validate. > > I could simply redefine parse() but I wonder how other people addressed this when > writing tests? Module ldif does not support change records at all. Ciao, Michael. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2398 bytes Desc: S/MIME Cryptographic Signature URL: From G.Bernhard at akbild.ac.at Wed Feb 19 08:52:11 2014 From: G.Bernhard at akbild.ac.at (Bernhard Gogo) Date: Wed, 19 Feb 2014 07:52:11 +0000 Subject: [python-ldap] =?windows-1252?q?python-ldap_gcc_error_unrecognized?= =?windows-1252?q?_option_=91-R=92?= Message-ID: Hello, every01! I am having serious trouble compiling python-ldap on debian for python2.4. This is what happens: 8<---------------- (python-ldap-2.4.14)zope09:~/python_ldap_dev_gogo/python-ldap-2.4.14# python setup.py build defines: HAVE_SASL HAVE_TLS HAVE_LIBLDAP_R extra_compile_args: extra_objects: include_dirs: /opt/openldap/include /usr/include/sasl /usr/include library_dirs: /opt/openldap/lib64 /usr/lib libs: ldap_r running build running build_py file Lib/ldap.py (for module ldap) not found file Lib/ldap/controls.py (for module ldap.controls) not found file Lib/ldap/extop.py (for module ldap.extop) not found file Lib/ldap/schema.py (for module ldap.schema) not found file Lib/ldap.py (for module ldap) not found file Lib/ldap/controls.py (for module ldap.controls) not found file Lib/ldap/extop.py (for module ldap.extop) not found file Lib/ldap/schema.py (for module ldap.schema) not found running egg_info writing requirements to Lib/python_ldap.egg-info/requires.txt writing Lib/python_ldap.egg-info/PKG-INFO writing top-level names to Lib/python_ldap.egg-info/top_level.txt writing dependency_links to Lib/python_ldap.egg-info/dependency_links.txt file Lib/ldap.py (for module ldap) not found file Lib/ldap/controls.py (for module ldap.controls) not found file Lib/ldap/extop.py (for module ldap.extop) not found file Lib/ldap/schema.py (for module ldap.schema) not found reading manifest file 'Lib/python_ldap.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' warning: no files found matching 'Makefile' warning: no files found matching 'Modules/LICENSE' writing manifest file 'Lib/python_ldap.egg-info/SOURCES.txt' running build_ext building '_ldap' extension /usr/bin/gcc -I/opt/plone3-instances/8009/Python-2.4/include -pthread -shared build/temp.linux-i686-2.4/Modules/LDAPObject.o build/temp.linux-i686-2.4/Modules/ldapcontrol.o build/temp.linux-i686-2.4/Modules/common.o build/temp.linux-i686-2.4/Modules/constants.o build/temp.linux-i686-2.4/Modules/errors.o build/temp.linux-i686-2.4/Modules/functions.o build/temp.linux-i686-2.4/Modules/schema.o build/temp.linux-i686-2.4/Modules/ldapmodule.o build/temp.linux-i686-2.4/Modules/message.o build/temp.linux-i686-2.4/Modules/version.o build/temp.linux-i686-2.4/Modules/options.o build/temp.linux-i686-2.4/Modules/berval.o -L/opt/openldap/lib64 -L/usr/lib -R/opt/openldap/lib64 -R/usr/lib -lldap_r -o build/lib.linux-i686-2.4/_ldap.so gcc: error: unrecognized option ?-R? gcc: error: unrecognized option ?-R? error: command '/usr/bin/gcc' failed with exit status 1 (python-ldap-2.4.14)zope09:~/python_ldap_dev_gogo/python-ldap-2.4.14# gcc --version gcc (Debian 4.7.2-5) 4.7.2 Copyright (C) 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. (python-ldap-2.4.14)zope09:~/python_ldap_dev_gogo/python-ldap-2.4.14# python Python 2.4.6 (#1, Dec 2 2013, 14:05:37) [GCC 4.7.2] on linux3 Type "help", "copyright", "credits" or "license" for more information. >>> ---------------->8 Obviously the "-R" option for gcc is wrong, but I can't figure out how to prevent the setup routines from injecting it. Older versions of gcc used to ignore it, but now it doesn't any more. I have to get a buildout setup running, and python-ldap fails. I have all dependencies installed and the machine's system Python has a working _ldap.so module. For this reproduction of the bug I used virtualenv. My buildout is broken unless I can fix that "-R" bug that emerged (due to the evolution of gcc). My buildout also compiles openldap in it's own seperate location without problems and tries to link against it, failing with the very same error. Any suggestions would be very appreciated! Gg. From bdauvergne at entrouvert.com Tue Mar 4 02:15:01 2014 From: bdauvergne at entrouvert.com (Benjamin Dauvergne) Date: Tue, 04 Mar 2014 02:15:01 +0100 Subject: [python-ldap] Project to support VLV and SSS controls... Message-ID: <53152915.3070501@entrouvert.com> I started a project to implement VLV and SSL controls[1], it's nearly finished. My intentions are to propose it for integration inside ldap.controls when it's really finished. My first tests gives strange results with OpenLDAP; my understanding of the control fields are wrong or OpenLDAP implementation is buged; I'm still not sure for now. [1]: https://github.com/bdauvergne/python-ldap-vlv From adam.polkosnik at ny.frb.org Tue Mar 4 18:26:38 2014 From: adam.polkosnik at ny.frb.org (Polkosnik, Adam) Date: Tue, 4 Mar 2014 17:26:38 +0000 Subject: [python-ldap] Error with expiring accounts Message-ID: <3fdlXH65Wlz7LpQ@mail.python.org> Hello there, Would anybody be willing to help me with getting to the bottom of this? I've set up LDAP for some webapp, and I get this error: LDAP Auth error: Received unexpected critical response control with controlType '2.16.840.1.113730.3.4.5' I'm using python-ldap-2.4.14, and it gets thrown for accounts that get the warning about the accounts that have a password expiration in a few days. Searching through the code, I figured that the handling should happen in Lib/ldap/controls/pwdpolicy.py since that's where the OID is defined. The error is generated in Lib/ldap/controls/__init__.py 136 knownLDAPControls = knownLDAPControls or KNOWN_RESPONSE_CONTROLS 137 result = [] 138 for controlType,criticality,encodedControlValue in ldapControlTuples or []: 139 try: 140 control = knownLDAPControls[controlType]() 141 except KeyError: 142 if criticality: 143 raise ldap.UNAVAILABLE_CRITICAL_EXTENSION('Received unexpected critical response control with controlType %s' % (repr(controlType))) 144 else: 145 control.controlType,control.criticality = controlType,criticality 146 try: 147 control.decodeControlValue(encodedControlValue) 148 except PyAsn1Error,e: 149 if criticality: 150 raise e 151 else: 152 result.append(control) 153 return result In my case I tried to get some more info through printing out more values in the exception: criticality =-1, encodedControlValue = 410453, repr(controlType) = 2.16.840.1.113730.3.4.5 also, I tried to get value of control, but got: LDAP Auth error: local variable 'control' referenced before assignment Thanks in advance, Adam Polkosnik This e-mail message, including attachments, is for the sole use of the intended recipient(s) and may contain confidential or proprietary information. If you are not the intended recipient, immediately contact the sender by reply e-mail and destroy all copies of the original message. -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at stroeder.com Tue Mar 4 19:48:15 2014 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Tue, 04 Mar 2014 19:48:15 +0100 Subject: [python-ldap] Error with expiring accounts In-Reply-To: <3fdlXH65Wlz7LpQ@mail.python.org> References: <3fdlXH65Wlz7LpQ@mail.python.org> Message-ID: <53161FEF.7090502@stroeder.com> Polkosnik, Adam wrote: > I've set up LDAP for some webapp, and I get this error: > > LDAP Auth error: Received unexpected critical response control with controlType '2.16.840.1.113730.3.4.5' Normally this should be handled automagically since this OID gets registered for class PasswordExpiringControl in ldap.control.KNOWN_RESPONSE_CONTROLS which is used as default in DecodeControlTuples(). Is the calling application mucking with key-word argument resp_ctrl_classes when invoking LDAPObject.result3() or LDAPObject.result4()? Ciao, Michael. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2398 bytes Desc: S/MIME Cryptographic Signature URL: From adam.polkosnik at ny.frb.org Tue Mar 4 20:35:14 2014 From: adam.polkosnik at ny.frb.org (Polkosnik, Adam) Date: Tue, 4 Mar 2014 19:35:14 +0000 Subject: [python-ldap] Error with expiring accounts In-Reply-To: <53161FEF.7090502@stroeder.com> References: <3fdlXH65Wlz7LpQ@mail.python.org> <53161FEF.7090502@stroeder.com> Message-ID: <3fdpN45Wr5z7Ljn@mail.python.org> I've not seen any mucking of any of those things, it goes something like this: import ldap, ldapurl try: ... l = ldap.initialize('ldap://myldapserver:1390') l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS,0) l.set_option(ldap.OPT_TIMEOUT, app_timeout) ... logger.info("Logging in username: %s" % usern) l.simple_bind_s(usern, userp) ... return usern except ldap.INVALID_CREDENTIALS: logger.info("Invalid credentials: %s" % usern) except Exception, err: logger.info("LDAP Auth error: %s" % err) Adam Polkosnik -----Original Message----- From: Michael Str?der [mailto:michael at stroeder.com] Sent: Tuesday, March 04, 2014 1:48 PM To: Polkosnik, Adam; python-ldap at python.org Subject: Re: [python-ldap] Error with expiring accounts Polkosnik, Adam wrote: > I've set up LDAP for some webapp, and I get this error: > > LDAP Auth error: Received unexpected critical response control with controlType '2.16.840.1.113730.3.4.5' Normally this should be handled automagically since this OID gets registered for class PasswordExpiringControl in ldap.control.KNOWN_RESPONSE_CONTROLS which is used as default in DecodeControlTuples(). Is the calling application mucking with key-word argument resp_ctrl_classes when invoking LDAPObject.result3() or LDAPObject.result4()? Ciao, Michael. This e-mail message, including attachments, is for the sole use of the intended recipient(s) and may contain confidential or proprietary information. If you are not the intended recipient, immediately contact the sender by reply e-mail and destroy all copies of the original message. From michael at stroeder.com Tue Mar 4 22:23:01 2014 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Tue, 04 Mar 2014 22:23:01 +0100 Subject: [python-ldap] Error with expiring accounts In-Reply-To: <20140304193529.4A3C260677@srv1.stroeder.com> References: <3fdlXH65Wlz7LpQ@mail.python.org> <53161FEF.7090502@stroeder.com> <20140304193529.4A3C260677@srv1.stroeder.com> Message-ID: <53164435.2080504@stroeder.com> Polkosnik, Adam wrote: > I've not seen any mucking of any of those things, it goes something like this: > > import ldap, ldapurl > try: > ... > l = ldap.initialize('ldap://myldapserver:1390') > l.protocol_version = 3 > l.set_option(ldap.OPT_REFERRALS,0) > l.set_option(ldap.OPT_TIMEOUT, app_timeout) > ... > logger.info("Logging in username: %s" % usern) > l.simple_bind_s(usern, userp) > ... > return usern > except ldap.INVALID_CREDENTIALS: > logger.info("Invalid credentials: %s" % usern) > except Exception, err: > logger.info("LDAP Auth error: %s" % err) You have to import ldap.controls.ppolicy and you need pyasn1 and pyasn1_modules to be installed for that to work. Ciao, Michael. P.S.: Please subscribe to the really low-traffic mailing list so I don't have to manually approve all your postings. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2398 bytes Desc: S/MIME Cryptographic Signature URL: From michael at stroeder.com Wed Mar 12 18:40:55 2014 From: michael at stroeder.com (Michael =?UTF-8?B?U3Ryw7ZkZXI=?=) Date: Wed, 12 Mar 2014 18:40:55 +0100 Subject: [python-ldap] Error with expiring accounts In-Reply-To: <20140312173453.9EB256038E@srv1.stroeder.com> References: <3fdlXH65Wlz7LpQ@mail.python.org> <53161FEF.7090502@stroeder.com> <20140304193529.4A3C260677@srv1.stroeder.com> <53164435.2080504@stroeder.com>, <20140312173453.9EB256038E@srv1.stroeder.com> Message-ID: <4ba7b4e83c43d9b6b4c9a692e2f03939@srv1.stroeder.com> On Wed, 12 Mar 2014 17:34:40 +0000 "Polkosnik, Adam" wrote > To me, it looks like that the classes/OIDs from pwdpolicy.py are not making > it into KNOWN_RESPONSE_CONTROLS. Works for me (first case without class PasswordPolicyControl as expected): Python 2.7.3 (default, Apr 14 2012, 08:58:41) [GCC] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import ldap.controls >>> ldap.controls.KNOWN_RESPONSE_CONTROLS {'1.3.6.1.4.1.4203.666.5.12': , '1.3.6.1.1.12': , '2.16.840.1.113730.3.4.2': , '1.2.840.113556.1.4.319': , '1.2.826.0.1.3344810.2.3': , '2.16.840.1.113730.3.4.15': } >>> import ldap.controls.ppolicy >>> ldap.controls.KNOWN_RESPONSE_CONTROLS {'1.3.6.1.4.1.4203.666.5.12': , '1.3.6.1.1.12': , '2.16.840.1.113730.3.4.2': , '1.3.6.1.4.1.42.2.27.8.5.1': , '1.2.840.113556.1.4.319': , '1.2.826.0.1.3344810.2.3': , '2.16.840.1.113730.3.4.15': } Anyway you could even register the class in ldap.controls.KNOWN_RESPONSE_CONTROLS yourself. Ciao, Michael. From adam.polkosnik at ny.frb.org Wed Mar 12 20:53:20 2014 From: adam.polkosnik at ny.frb.org (Polkosnik, Adam) Date: Wed, 12 Mar 2014 19:53:20 +0000 Subject: [python-ldap] Error with expiring accounts In-Reply-To: <4ba7b4e83c43d9b6b4c9a692e2f03939@srv1.stroeder.com> References: <3fdlXH65Wlz7LpQ@mail.python.org> <53161FEF.7090502@stroeder.com> <20140304193529.4A3C260677@srv1.stroeder.com> <53164435.2080504@stroeder.com>, <20140312173453.9EB256038E@srv1.stroeder.com> <4ba7b4e83c43d9b6b4c9a692e2f03939@srv1.stroeder.com> Message-ID: <3fkkPH4rb5zRNM@mail.python.org> I really don?t see where you have those values (they are listed in Lib/ldap/controls/pwdpolicy.py): 2.16.840.1.113730.3.4.4 - Netscape Password Expired LDAPv3 control 2.16.840.1.113730.3.4.5 - Netscape Password Expiring LDAPv3 control (OIDs descriptions from: http://www.alvestrand.no/objectid/2.16.840.1.113730.3.4.html) I can see that you have this: '2.16.840.1.113730.3.4.2': And that comes from Lib/ldap/controls/simple.py:78 So, now I understand that out of the box the __init__.py imports only: # Import the standard sub-modules from ldap.controls.simple import * from ldap.controls.libldap import * and I have to import ldap.controls.pwdpolicy manually, but there's a problem: It seems that there was a line missing in Setup.py (I guess since that module is borked): In py_modules[] (towards the bottom) 'ldap.controls.pwdpolicy' But after that fix, it seems that it really was broken... >>> import ldap.controls.pwdpolicy Traceback (most recent call last): File "", line 1, in File "/usr/lib/python2.7/site-packages/ldap/controls/pwdpolicy.py", line 20, in class PasswordExpiringControl(OctetStringInteger): NameError: name 'OctetStringInteger' is not defined Adding the missing imports to pwdpolicy.py makes it almost work: import struct from ldap.controls.simple import OctetStringInteger >>> l.simple_bind_s( un, password) Traceback (most recent call last): File "", line 1, in File "/usr/lib/python2.7/site-packages/ldap/ldapobject.py", line 208, in simple_bind_s resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all=1,timeout=self.timeout) File "/usr/lib/python2.7/site-packages/ldap/ldapobject.py", line 469, in result3 resp_ctrl_classes=resp_ctrl_classes File "/usr/lib/python2.7/site-packages/ldap/ldapobject.py", line 487, in result4 decoded_resp_ctrls = DecodeControlTuples(resp_ctrls,resp_ctrl_classes) File "/usr/lib/python2.7/site-packages/ldap/controls/__init__.py", line 147, in DecodeControlTuples control.decodeControlValue(encodedControlValue) File "/usr/lib/python2.7/site-packages/ldap/controls/pwdpolicy.py", line 30, in decodeControlValue self.gracePeriod = struct.unpack('!Q',encodedControlValue)[0] struct.error: unpack requires a string argument of length 8 So, at this point it's complaining that the encodedControlValue is shorter than 8 bytes?! Dow we just get rid of the unpack and assign the value? At least that seemed to work ok. -----Original Message----- From: Michael Str?der [mailto:michael at stroeder.com] Sent: Wednesday, March 12, 2014 1:41 PM To: python-ldap at python.org; Polkosnik, Adam Subject: Re: [python-ldap] Error with expiring accounts On Wed, 12 Mar 2014 17:34:40 +0000 "Polkosnik, Adam" wrote > To me, it looks like that the classes/OIDs from pwdpolicy.py are not > making it into KNOWN_RESPONSE_CONTROLS. Works for me (first case without class PasswordPolicyControl as expected): Python 2.7.3 (default, Apr 14 2012, 08:58:41) [GCC] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import ldap.controls >>> ldap.controls.KNOWN_RESPONSE_CONTROLS {'1.3.6.1.4.1.4203.666.5.12': , '1.3.6.1.1.12': ldap.controls.libldap.AssertionControl at 0x7fb74dcaf0b8>, '2.16.840.1.113730.3.4.2': , '1.2.840.113556.1.4.319': , '1.2.826.0.1.3344810.2.3': , '2.16.840.1.113730.3.4.15': } >>> import ldap.controls.ppolicy >>> ldap.controls.KNOWN_RESPONSE_CONTROLS {'1.3.6.1.4.1.4203.666.5.12': , '1.3.6.1.1.12': ldap.controls.libldap.AssertionControl at 0x7fb74dcaf0b8>, '2.16.840.1.113730.3.4.2': , '1.3.6.1.4.1.42.2.27.8.5.1': , '1.2.840.113556.1.4.319': , '1.2.826.0.1.3344810.2.3': , '2.16.840.1.113730.3.4.15': } Anyway you could even register the class in ldap.controls.KNOWN_RESPONSE_CONTROLS yourself. Ciao, Michael. This e-mail message, including attachments, is for the sole use of the intended recipient(s) and may contain confidential or proprietary information. If you are not the intended recipient, immediately contact the sender by reply e-mail and destroy all copies of the original message. From michael at stroeder.com Wed Mar 12 21:20:33 2014 From: michael at stroeder.com (=?UTF-8?B?TWljaGFlbCBTdHLDtmRlcg==?=) Date: Wed, 12 Mar 2014 21:20:33 +0100 Subject: [python-ldap] Error with expiring accounts In-Reply-To: <20140312195335.BBC78603A3@srv1.stroeder.com> References: <3fdlXH65Wlz7LpQ@mail.python.org> <53161FEF.7090502@stroeder.com> <20140304193529.4A3C260677@srv1.stroeder.com> <53164435.2080504@stroeder.com>, <20140312173453.9EB256038E@srv1.stroeder.com> <4ba7b4e83c43d9b6b4c9a692e2f03939@srv1.stroeder.com> <20140312195335.BBC78603A3@srv1.stroeder.com> Message-ID: <5320C191.2070703@stroeder.com> Polkosnik, Adam wrote: > > I really don?t see where you have those values (they are listed in Lib/ldap/controls/pwdpolicy.py): > > 2.16.840.1.113730.3.4.4 - Netscape Password Expired LDAPv3 control > 2.16.840.1.113730.3.4.5 - Netscape Password Expiring LDAPv3 control Ouch! I've overlooked that you're talking about pwdpolicy and not ppolicy. Sorry. http://tools.ietf.org/html/draft-vchu-ldap-pwd-policy May I ask which LDAP server that is? Actually the (ancient) I-D above specifies that the server returns this response control with criticality: false. > Adding the missing imports to pwdpolicy.py makes it almost work: > > self.gracePeriod = struct.unpack('!Q',encodedControlValue)[0] > struct.error: unpack requires a string argument of length 8 > > So, at this point it's complaining that the encodedControlValue is shorter than 8 bytes?! > > Dow we just get rid of the unpack and assign the value? At least that seemed to work ok. Hmm, it seems I don't have such a LDAP server to test. Could you please send repr(encodedControlValue) and determine how many seconds the grace period really is? Ciao, Michael. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2398 bytes Desc: S/MIME Cryptographic Signature URL: From adam.polkosnik at ny.frb.org Wed Mar 12 21:46:52 2014 From: adam.polkosnik at ny.frb.org (Polkosnik, Adam) Date: Wed, 12 Mar 2014 20:46:52 +0000 Subject: [python-ldap] Error with expiring accounts In-Reply-To: <5320C191.2070703@stroeder.com> References: <3fdlXH65Wlz7LpQ@mail.python.org> <53161FEF.7090502@stroeder.com> <20140304193529.4A3C260677@srv1.stroeder.com> <53164435.2080504@stroeder.com>, <20140312173453.9EB256038E@srv1.stroeder.com> <4ba7b4e83c43d9b6b4c9a692e2f03939@srv1.stroeder.com> <20140312195335.BBC78603A3@srv1.stroeder.com> <5320C191.2070703@stroeder.com> Message-ID: <3fklb73nx5zQMR@mail.python.org> In class PasswordExpiringControl: def decodeControlValue(self,encodedControlValue): self.gracePeriod = encodedControlValue print repr(encodedControlValue) print repr(encodedControlValue[0]) #self.gracePeriod = struct.unpack('!Q',encodedControlValue)[0] >>> l.simple_bind_s( un, password) '349853' '3' (97, [], 1, []) It looks like 349853 is a tad above 4 days, so it should be the actual number of seconds until password expiration. Thanks, Adam -----Original Message----- From: Michael Str?der [mailto:michael at stroeder.com] Sent: Wednesday, March 12, 2014 4:21 PM To: Polkosnik, Adam; python-ldap at python.org Subject: Re: [python-ldap] Error with expiring accounts Polkosnik, Adam wrote: > > I really don?t see where you have those values (they are listed in Lib/ldap/controls/pwdpolicy.py): > > 2.16.840.1.113730.3.4.4 - Netscape Password Expired LDAPv3 control > 2.16.840.1.113730.3.4.5 - Netscape Password Expiring LDAPv3 control Ouch! I've overlooked that you're talking about pwdpolicy and not ppolicy. Sorry. http://tools.ietf.org/html/draft-vchu-ldap-pwd-policy May I ask which LDAP server that is? Actually the (ancient) I-D above specifies that the server returns this response control with criticality: false. > Adding the missing imports to pwdpolicy.py makes it almost work: > > self.gracePeriod = struct.unpack('!Q',encodedControlValue)[0] > struct.error: unpack requires a string argument of length 8 > > So, at this point it's complaining that the encodedControlValue is shorter than 8 bytes?! > > Dow we just get rid of the unpack and assign the value? At least that seemed to work ok. Hmm, it seems I don't have such a LDAP server to test. Could you please send repr(encodedControlValue) and determine how many seconds the grace period really is? Ciao, Michael. This e-mail message, including attachments, is for the sole use of the intended recipient(s) and may contain confidential or proprietary information. If you are not the intended recipient, immediately contact the sender by reply e-mail and destroy all copies of the original message. From michael at stroeder.com Wed Mar 12 22:01:02 2014 From: michael at stroeder.com (=?UTF-8?B?TWljaGFlbCBTdHLDtmRlcg==?=) Date: Wed, 12 Mar 2014 22:01:02 +0100 Subject: [python-ldap] Error with expiring accounts In-Reply-To: <20140312204938.1C60160253@srv1.stroeder.com> References: <3fdlXH65Wlz7LpQ@mail.python.org> <53161FEF.7090502@stroeder.com> <20140304193529.4A3C260677@srv1.stroeder.com> <53164435.2080504@stroeder.com>, <20140312173453.9EB256038E@srv1.stroeder.com> <4ba7b4e83c43d9b6b4c9a692e2f03939@srv1.stroeder.com> <20140312195335.BBC78603A3@srv1.stroeder.com> <5320C191.2070703@stroeder.com> <20140312204938.1C60160253@srv1.stroeder.com> Message-ID: <5320CB0E.8020902@stroeder.com> Polkosnik, Adam wrote: > In class PasswordExpiringControl: > > def decodeControlValue(self,encodedControlValue): > self.gracePeriod = encodedControlValue > print repr(encodedControlValue) > print repr(encodedControlValue[0]) > #self.gracePeriod = struct.unpack('!Q',encodedControlValue)[0] > > > >>>> l.simple_bind_s( un, password) > '349853' > '3' > (97, [], 1, []) > > > It looks like 349853 is a tad above 4 days, so it should be the actual number of seconds until password expiration. Hmm, a string of digits indicating the seconds...that's not how I read draft-vchu-ldap-pwd-policy. IMO there are two server-side bugs here (not unusual for the vendor you mentioned off-list): 1. In violation to the I-D it sends the response control with criticality=true so clients cannot safely ignore it. 2. The response control value has wrong encoding. For a quick solution I'd suggest that you sub-class ldap.controls.pwdpolicy.PasswordExpiringControl overriding method decodeControlValue() to implement whatever is needed for that particular server implementation. Ciao, Michael. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2398 bytes Desc: S/MIME Cryptographic Signature URL: From michael at stroeder.com Wed Mar 12 22:16:26 2014 From: michael at stroeder.com (=?UTF-8?B?TWljaGFlbCBTdHLDtmRlcg==?=) Date: Wed, 12 Mar 2014 22:16:26 +0100 Subject: [python-ldap] Error with expiring accounts In-Reply-To: <5320CB0E.8020902@stroeder.com> References: <3fdlXH65Wlz7LpQ@mail.python.org> <53161FEF.7090502@stroeder.com> <20140304193529.4A3C260677@srv1.stroeder.com> <53164435.2080504@stroeder.com>, <20140312173453.9EB256038E@srv1.stroeder.com> <4ba7b4e83c43d9b6b4c9a692e2f03939@srv1.stroeder.com> <20140312195335.BBC78603A3@srv1.stroeder.com> <5320C191.2070703@stroeder.com> <20140312204938.1C60160253@srv1.stroeder.com> <5320CB0E.8020902@stroeder.com> Message-ID: <5320CEAA.404@stroeder.com> Michael Str?der wrote: > Polkosnik, Adam wrote: >> In class PasswordExpiringControl: >> >> def decodeControlValue(self,encodedControlValue): >> self.gracePeriod = encodedControlValue >> print repr(encodedControlValue) >> print repr(encodedControlValue[0]) >> #self.gracePeriod = struct.unpack('!Q',encodedControlValue)[0] >> >> >> >>>>> l.simple_bind_s( un, password) >> '349853' >> '3' >> (97, [], 1, []) >> >> >> It looks like 349853 is a tad above 4 days, so it should be the actual number of seconds until password expiration. > > Hmm, a string of digits indicating the seconds...that's not how I read > draft-vchu-ldap-pwd-policy. I stand corrected: https://lists.forgerock.org/pipermail/opendj/2014-March/003730.html Please check out CVS HEAD and test whether that works for you. Ciao, Michael. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2398 bytes Desc: S/MIME Cryptographic Signature URL: From adam.polkosnik at ny.frb.org Wed Mar 12 23:02:18 2014 From: adam.polkosnik at ny.frb.org (Polkosnik, Adam) Date: Wed, 12 Mar 2014 22:02:18 +0000 Subject: [python-ldap] Error with expiring accounts In-Reply-To: <5320CEAA.404@stroeder.com> References: <3fdlXH65Wlz7LpQ@mail.python.org> <53161FEF.7090502@stroeder.com> <20140304193529.4A3C260677@srv1.stroeder.com> <53164435.2080504@stroeder.com>, <20140312173453.9EB256038E@srv1.stroeder.com> <4ba7b4e83c43d9b6b4c9a692e2f03939@srv1.stroeder.com> <20140312195335.BBC78603A3@srv1.stroeder.com> <5320C191.2070703@stroeder.com> <20140312204938.1C60160253@srv1.stroeder.com> <5320CB0E.8020902@stroeder.com> <5320CEAA.404@stroeder.com> Message-ID: <3fknG63zY5z7LjM@mail.python.org> Works for me. Thanks! -----Original Message----- From: Michael Str?der [mailto:michael at stroeder.com] Sent: Wednesday, March 12, 2014 5:16 PM To: Polkosnik, Adam; python-ldap at python.org Subject: Re: [python-ldap] Error with expiring accounts Michael Str?der wrote: > Polkosnik, Adam wrote: >> In class PasswordExpiringControl: >> >> def decodeControlValue(self,encodedControlValue): >> self.gracePeriod = encodedControlValue >> print repr(encodedControlValue) >> print repr(encodedControlValue[0]) >> #self.gracePeriod = struct.unpack('!Q',encodedControlValue)[0] >> >> >> >>>>> l.simple_bind_s( un, password) >> '349853' >> '3' >> (97, [], 1, [> instance at 0x7f1ae5b1f098>]) >> >> >> It looks like 349853 is a tad above 4 days, so it should be the actual number of seconds until password expiration. > > Hmm, a string of digits indicating the seconds...that's not how I read > draft-vchu-ldap-pwd-policy. I stand corrected: https://lists.forgerock.org/pipermail/opendj/2014-March/003730.html Please check out CVS HEAD and test whether that works for you. Ciao, Michael. This e-mail message, including attachments, is for the sole use of the intended recipient(s) and may contain confidential or proprietary information. If you are not the intended recipient, immediately contact the sender by reply e-mail and destroy all copies of the original message. From adam.polkosnik at ny.frb.org Wed Mar 12 18:34:40 2014 From: adam.polkosnik at ny.frb.org (Polkosnik, Adam) Date: Wed, 12 Mar 2014 17:34:40 +0000 Subject: [python-ldap] Error with expiring accounts In-Reply-To: <53164435.2080504@stroeder.com> References: <3fdlXH65Wlz7LpQ@mail.python.org> <53161FEF.7090502@stroeder.com> <20140304193529.4A3C260677@srv1.stroeder.com> <53164435.2080504@stroeder.com> Message-ID: <3fkgLc45Mdz7LjN@mail.python.org> I did have pyasn1 and pyasn1_modules imported, as well as ldap.controls.ppolicy, but still this is what it throws for accounts with a password expiration warning. To me, it looks like that the OIDs from pwdpolicy.py are not making it into KNOWN_RESPONSE_CONTROLS. >>> l.simple_bind_s( username, password) Traceback (most recent call last): File "", line 1, in File "/usr/lib/python2.7/site-packages/ldap/ldapobject.py", line 208, in simple_bind_s resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all=1,timeout=self.timeout) File "/usr/lib/python2.7/site-packages/ldap/ldapobject.py", line 469, in result3 resp_ctrl_classes=resp_ctrl_classes File "/usr/lib/python2.7/site-packages/ldap/ldapobject.py", line 487, in result4 decoded_resp_ctrls = DecodeControlTuples(resp_ctrls,resp_ctrl_classes) File "/usr/lib/python2.7/site-packages/ldap/controls/__init__.py", line 143, in DecodeControlTuples raise ldap.UNAVAILABLE_CRITICAL_EXTENSION('Received unexpected critical response control with controlType %s' % (repr(controlType))) ldap.UNAVAILABLE_CRITICAL_EXTENSION: Received unexpected critical response control with controlType '2.16.840.1.113730.3.4.5' To me, it looks like that the classes/OIDs from pwdpolicy.py are not making it into KNOWN_RESPONSE_CONTROLS. >>> from ldap.controls import KNOWN_RESPONSE_CONTROLS >>> print KNOWN_RESPONSE_CONTROLS {'1.3.6.1.4.1.4203.666.5.12': , '1.3.6.1.1.12': , '2.16.840.1.113730.3.4.2': , '1.3.6.1.4.1.42.2.27.8.5.1': , '1.2.840.113556.1.4.319': , '1.2.826.0.1.3344810.2.3': , '2.16.840.1.113730.3.4.15': } -----Original Message----- From: Michael Str?der [mailto:michael at stroeder.com] Sent: Tuesday, March 04, 2014 4:23 PM To: Polkosnik, Adam; python-ldap at python.org Subject: Re: [python-ldap] Error with expiring accounts Polkosnik, Adam wrote: > I've not seen any mucking of any of those things, it goes something like this: > > import ldap, ldapurl > try: > ... > l = ldap.initialize('ldap://myldapserver:1390') > l.protocol_version = 3 > l.set_option(ldap.OPT_REFERRALS,0) > l.set_option(ldap.OPT_TIMEOUT, app_timeout) > ... > logger.info("Logging in username: %s" % usern) > l.simple_bind_s(usern, userp) > ... > return usern > except ldap.INVALID_CREDENTIALS: > logger.info("Invalid credentials: %s" % usern) > except Exception, err: > logger.info("LDAP Auth error: %s" % err) You have to import ldap.controls.ppolicy and you need pyasn1 and pyasn1_modules to be installed for that to work. Ciao, Michael. P.S.: Please subscribe to the really low-traffic mailing list so I don't have to manually approve all your postings. This e-mail message, including attachments, is for the sole use of the intended recipient(s) and may contain confidential or proprietary information. If you are not the intended recipient, immediately contact the sender by reply e-mail and destroy all copies of the original message. From martin.pfeifer at gmail.com Sun Mar 23 19:54:52 2014 From: martin.pfeifer at gmail.com (Martin Pfeifer) Date: Sun, 23 Mar 2014 19:54:52 +0100 Subject: [python-ldap] SASL + REALM Message-ID: Hi there, i had a similar problem using SASL. After digging in the python-ldap code and the header files of cyrus-sasl and openldap to understand what is going on i found that the constant ldap.sasl.CB_GETREALM in python-ldap is set to 0x4007 but the sasl.h states that the callback id of CB_GETREALM is 0x4008. I reassigned ldap.sasl.CB_GETREALM with 0x4008 in my script and that did the trick. As of my understanding this is a bug in python-ldap and needs fixing. Best regards Martin Pfeifer snippet from sasl.h #define SASL_CB_GETREALM (0x4008) /* realm to attempt authentication in */ snippet from python-ldap/Lib/ldap/sasl.py These are the SASL callback id's , as defined in sasl.h CB_USER = 0x4001 CB_AUTHNAME = 0x4002 CB_LANGUAGE = 0x4003 CB_PASS = 0x4004 CB_ECHOPROMPT = 0x4005 CB_NOECHOPROMPT= 0x4006 CB_GETREALM = 0x4007 <-- this should be 0x4008 -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at stroeder.com Sun Mar 23 20:07:58 2014 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Sun, 23 Mar 2014 20:07:58 +0100 Subject: [python-ldap] SASL + REALM In-Reply-To: References: Message-ID: <532F310E.3040409@stroeder.com> Martin Pfeifer wrote: > i had a similar problem using SASL. After digging in the python-ldap code > and the header files of cyrus-sasl and openldap to understand what is going > on i found that the constant ldap.sasl.CB_GETREALM in python-ldap is set to > 0x4007 but the sasl.h states that the callback id of CB_GETREALM is 0x4008. > I reassigned ldap.sasl.CB_GETREALM with 0x4008 in my script and that did > the trick. As of my understanding this is a bug in python-ldap and needs > fixing. I've committed the patch below. Thanks for reporting it. Ciao, Michael. Index: Lib/ldap/sasl.py =================================================================== RCS file: /cvsroot/python-ldap/python-ldap/Lib/ldap/sasl.py,v retrieving revision 1.15 diff -u -r1.15 sasl.py --- Lib/ldap/sasl.py 26 Jul 2009 11:09:58 -0000 1.15 +++ Lib/ldap/sasl.py 23 Mar 2014 19:05:15 -0000 @@ -31,7 +31,7 @@ CB_PASS = 0x4004 CB_ECHOPROMPT = 0x4005 CB_NOECHOPROMPT= 0x4006 -CB_GETREALM = 0x4007 +CB_GETREALM = 0x4008 class sasl: """This class handles SASL interactions for authentication. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2398 bytes Desc: S/MIME Cryptographic Signature URL: From michael at stroeder.com Mon Mar 24 11:26:14 2014 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Mon, 24 Mar 2014 11:26:14 +0100 Subject: [python-ldap] ANN: python-ldap 2.4.15 Message-ID: <53300846.9000501@stroeder.com> Find a new release of python-ldap: http://pypi.python.org/pypi/python-ldap/2.4.15 python-ldap provides an object-oriented API to access LDAP directory servers from Python programs. It mainly wraps the OpenLDAP 2.x libs for that purpose. Additionally it contains modules for other LDAP-related stuff (e.g. processing LDIF, LDAP URLs and LDAPv3 schema). Project's web site: http://www.python-ldap.org/ Ciao, Michael. ---------------------------------------------------------------- Released 2.4.15 2014-03-24 Changes since 2.4.14: Lib/ * Added missing modules ldap.controls.openldap and ldap.controls.pwdpolicy to setup.py * Added missing imports to ldap.controls.pwdpolicy * Fixed ldap.controls.pwdpolicy.decodeControlValue() to decode string of digits * Support for X-SUBST in schema element class LDAPSyntax * Support for X-ORDERED and X-ORIGIN in schema element class AttributeType * ldapurl: New scope 'subordinates' defined in draft-sermersheim-ldap-subordinate-scope Modules/ * New constant ldap.SCOPE_SUBORDINATE derived from ldap.h for draft-sermersheim-ldap-subordinate-scope * Fixed constant ldap.sasl.CB_GETREALM (thanks to Martin Pfeifer) From raphael.barrois at m4x.org Tue Mar 25 00:43:33 2014 From: raphael.barrois at m4x.org (=?UTF-8?B?UmFwaGHDq2w=?= Barrois) Date: Tue, 25 Mar 2014 00:43:33 +0100 Subject: [python-ldap] Python3 compatibility Message-ID: <20140325004333.19c4fe16@anoth> Hi, I've been working on a Python3 patch for the python-ldap library, with the goal of having a single codebase for both Py2 and Py3 families. The patch applies cleanly on master, and the whole test suite passes (except a test that was already broken). Obviously, the biggest issue is on the "bytes vs. unicode" side; I had to make a few choices: * Query results (from search_ext et al.) return a list of (dn, fields) tuples, where: - dn is bytes (UTF-8 encoded) in both Py2 (str) and Py3 (bytes) - fields is a dict mapping a field (as text, unicode in Py2 and str in Py3) to a list of values, as bytes in both versions (this can contain images, etc.) * Query filters is expected: - As text (unicode) in Py3 - As bytes or text in Py2, with text being "in the default encoding" * When sending data, the value of attributes *must* be bytes in both Py2 (str) and Py3 (bytes) This means that the same Python code should be able to run identically on Py2 and Py3 with the same version of Python-ldap, provided the "default encoding" is UTF-8. We've been running both forms of this patch in production for a couple of months without any issue. The source of the patch is available on my Github fork, split in several commits for readability: https://github.com/rbarrois/python-ldap/compare/py3 Could this be merged into the master? Note: I know that a "python3-ldap" lib exists, but it isn't as integrated as python-ldap in most libraries, and lacks a few useful features (SASL connection, paged queries, etc.). -- Rapha?l -------------- next part -------------- A non-text attachment was scrubbed... Name: py3.patch Type: text/x-patch Size: 106877 bytes Desc: not available URL: From richard at thewisewolf.com Thu Mar 27 05:17:57 2014 From: richard at thewisewolf.com (Richard Li) Date: Wed, 26 Mar 2014 23:17:57 -0500 Subject: [python-ldap] search_s() appends failed referral references as results Message-ID: I'm working with some code that does LDAP authentication against ActiveDirectory, and I'm tracking an error down to a strange behavior in the search_s() of LDAPObject: It seems when a referral reference is returned with search results and referral reference couldn't be reached, search_s() leaves the them in the returned result list as a tuple (None, ['ldap://referral_uri']) Is that an intended behavior of search_s() ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at stroeder.com Thu Mar 27 08:47:50 2014 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Thu, 27 Mar 2014 08:47:50 +0100 Subject: [python-ldap] search_s() appends failed referral references as results In-Reply-To: References: Message-ID: <5333D7A6.3090405@stroeder.com> Richard Li wrote: > I'm working with some code that does LDAP authentication against > ActiveDirectory, and I'm tracking an error down to a strange behavior in > the search_s() of LDAPObject: > > It seems when a referral reference is returned with search results and > referral reference couldn't be reached, search_s() leaves the them in the > returned result list as a tuple (None, ['ldap://referral_uri']) > > Is that an intended behavior of search_s() ? Yes, that's correct. Otherwise you would'nt receive search continuations. You should simply sort them out. BTW: You could configure your application to use the global catalog. No search continuations are returned by AD in this case. The caveat is that not all user entry attributes are available there. Ciao, Michael. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2398 bytes Desc: S/MIME Cryptographic Signature URL: From jsf80238 at gmail.com Thu Mar 27 15:22:55 2014 From: jsf80238 at gmail.com (Jason Friedman) Date: Thu, 27 Mar 2014 08:22:55 -0600 Subject: [python-ldap] Python 3 support Message-ID: Hello, if I were to run 2to3 on all of the files would I be set for using this with Python 3? I currently have special 2-only code to use this library (which is very much appreciated), being able to use it with Python 3 would be nice. -------------- next part -------------- An HTML attachment was scrubbed... URL: From raphael.barrois at m4x.org Thu Mar 27 23:57:08 2014 From: raphael.barrois at m4x.org (=?UTF-8?B?UmFwaGHDq2w=?= Barrois) Date: Thu, 27 Mar 2014 23:57:08 +0100 Subject: [python-ldap] Python 3 support In-Reply-To: References: Message-ID: <20140327235708.781501ff@anoth> On Thu, 27 Mar 2014 08:22:55 -0600 Jason Friedman wrote: > Hello, if I were to run 2to3 on all of the files would I be set for using > this with Python 3? > > I currently have special 2-only code to use this library (which is very > much appreciated), being able to use it with Python 3 would be nice. Hi, python-ldap doesn't support Python3 yet; however, I've been working on a "Py2/Py3 single codebase" patch, available at https://github.com/rbarrois/python-ldap/tree/py3 I've described the various changes and specifics here: https://mail.python.org/pipermail/python-ldap/2014q1/003348.html Hope this helps! -- Rapha?l From richard at thewisewolf.com Fri Mar 28 02:58:14 2014 From: richard at thewisewolf.com (Richard Li) Date: Thu, 27 Mar 2014 20:58:14 -0500 Subject: [python-ldap] search_s() appends failed referral references as results In-Reply-To: <5333D7A6.3090405@stroeder.com> References: <5333D7A6.3090405@stroeder.com> Message-ID: Thanks. Maybe such behavior should be mentioned in the documentation? Right now it does not mention anything about referral objects and only states (dn, attrs) is (str, dict) tuple. On Thu, Mar 27, 2014 at 2:47 AM, Michael Str?der wrote: > Richard Li wrote: > > I'm working with some code that does LDAP authentication against > > ActiveDirectory, and I'm tracking an error down to a strange behavior in > > the search_s() of LDAPObject: > > > > It seems when a referral reference is returned with search results and > > referral reference couldn't be reached, search_s() leaves the them in the > > returned result list as a tuple (None, ['ldap://referral_uri']) > > > > Is that an intended behavior of search_s() ? > > Yes, that's correct. Otherwise you would'nt receive search continuations. > You > should simply sort them out. > > BTW: You could configure your application to use the global catalog. No > search > continuations are returned by AD in this case. The caveat is that not all > user > entry attributes are available there. > > Ciao, Michael. > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at stroeder.com Fri Mar 28 07:34:54 2014 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Fri, 28 Mar 2014 07:34:54 +0100 Subject: [python-ldap] search_s() appends failed referral references as results In-Reply-To: References: <5333D7A6.3090405@stroeder.com> Message-ID: <5335180E.2070404@stroeder.com> Richard Li wrote: > Maybe such behavior should be mentioned in the documentation? Right now it > does not mention anything about referral objects and only states (dn, > attrs) is (str, dict) tuple. Yes. Feel free to submit a doc patch. Ciao, Michael. > On Thu, Mar 27, 2014 at 2:47 AM, Michael Str?der wrote: > >> Richard Li wrote: >>> I'm working with some code that does LDAP authentication against >>> ActiveDirectory, and I'm tracking an error down to a strange behavior in >>> the search_s() of LDAPObject: >>> >>> It seems when a referral reference is returned with search results and >>> referral reference couldn't be reached, search_s() leaves the them in the >>> returned result list as a tuple (None, ['ldap://referral_uri']) >>> >>> Is that an intended behavior of search_s() ? >> >> Yes, that's correct. Otherwise you would'nt receive search continuations. >> You >> should simply sort them out. >> >> BTW: You could configure your application to use the global catalog. No >> search >> continuations are returned by AD in this case. The caveat is that not all >> user >> entry attributes are available there. >> >> Ciao, Michael. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2398 bytes Desc: S/MIME Cryptographic Signature URL: