From paulobruck1 at gmail.com Sat Oct 5 19:32:12 2013 From: paulobruck1 at gmail.com (paulo bruck) Date: Sat, 5 Oct 2013 14:32:12 -0300 Subject: [python-ldap] ldap.schema Message-ID: Hi Guys I am still studying python and python-ldap. >From now I could do a lot of thins reading and seen examples, but now I am facing a great difficultie trying to mount a script could show me from cn=schema all atributes witch are MUST and MAY. I know that I have to import ldap.schema and use subschema_subentry and attribute_types, but could not find a way to solve my problem. I try to read pyhon-ldap docs( but unfortunatelly there is only a import ldap.schema as example... 80) and http://www.packtpub.com/article/python-ldap-applications-ldap-schema which uses a ldaphelper with there is no pachage for debian wheezy...) Anyone could give a help or show me a place w/ examples? Thanks in advanced -- Paulo Ricardo Bruck consultor tel 011 3596-4881/4882 011 98140-9184 (TIM) http://www.contatogs.com.br http://www.protejasuarede.com.br -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at stroeder.com Mon Oct 7 09:49:52 2013 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Mon, 07 Oct 2013 09:49:52 +0200 Subject: [python-ldap] ldap.schema In-Reply-To: References: Message-ID: <525267A0.7070609@stroeder.com> paulo bruck wrote: > but now I am > facing a great difficultie trying to mount a script could show me from > cn=schema all atributes witch are MUST and MAY. That's what method ldap.schema.subentry.SubSchema.attribute_types() is for: http://www.python-ldap.org/doc/html/ldap-schema.html#ldap.schema.subentry.SubSchema.attribute_types This is used in Demo/schema.py which is part of python-ldap's source distribution. 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 Mon Oct 14 21:02:49 2013 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Mon, 14 Oct 2013 21:02:49 +0200 Subject: [python-ldap] FYI: talk at LDAPcon 2013 Message-ID: <525C3FD9.6020301@stroeder.com> HI! The following talk will be presented by me at LDAPcon 2013, on Tuesday 19th November 2013: Do The Right Thing! How LDAP servers should help LDAP clients Of course there are many more interesting talks on two days 18.11. and 19.11.: http://ldapcon.org/#program Hope to see you there! Ciao, Michael. ---------------------- snip ---------------------- Title: Do The Right Thing! How LDAP servers should help LDAP clients Abstract: This talk is about the highs and lows of implementing a generic interactive LDAP client with web2ldap to be shown as example (because the author is biased of course). The main focus of this talk is to point out how important it is to have common standard mechanisms to provide information to interactive clients so the implementations can guide the user to do things right. - rootDSE - vendor information - using schema at the client side (templating, plugins, fall-backs) - how to truly optionally handle DIT content and structure rules, name forms - number of entries/values - find out about server-side access control (arrgh!) - find out about server-side constraints? - dealing with user's preferences - audit logs Some of this topics are shown with test servers of various vendors, some of the topics should be viewed as possible work items for standardization. -------------- 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 mail at eliasprobst.eu Wed Oct 16 00:33:31 2013 From: mail at eliasprobst.eu (Elias Probst) Date: Wed, 16 Oct 2013 00:33:31 +0200 Subject: [python-ldap] Validated URL can't be used for bind - handling SRV lookups Message-ID: <525DC2BB.3090408@eliasprobst.eu> Hi list, I'm working on improvements to the LDAP authentication module for 'Salt' (Saltstack): https://github.com/saltstack/salt/blob/develop/salt/auth/ldap.py I planned to make it possible to use URLs like this: ldap:///dc=company,dc=tld When using such an URL on the commandline (e.g. ldapsearch) this will cause a DNS lookup to retrieve SRV records from DNS contining pointers to LDAP hosts and their ports which will then be used to bind to. python-ldap validates such an URL just fine using ldapurl.isLDAPUrl(), but actually using in in ldap.initialize() will fail. Below is some output and test code: -->snip - Output<-- Valid: ldap:///dc=institution,dc=de initialize() failed: ldap:///dc=institution,dc=de - (2, 'No such file or directory') Valid: ldap:///dc%3Dinstitution%2Cdc%3Dde initialize() succeeded: ldap:///dc%3Dinstitution%2Cdc%3Dde bind failed: {'desc': "Can't contact LDAP server"} Valid: ldap://u-dc01.institution.de:389 initialize() succeeded: ldap://u-dc01.institution.de:389 bind succeeded -->snap - Output<-- -->snip - Code<-- #!/usr/bin/python import ldap import ldapurl urldict = { 'ldap://u-dc01.institution.de:389', 'ldap:///dc=institution,dc=de', 'ldap:///dc%3Dinstitution%2Cdc%3Dde', } binddn='user at institution.de' bindpw='somepassword' for url in urldict: # validate if ldapurl.isLDAPUrl(url): print 'Valid: {0}'.format(url) else: print 'Invalid: {0}'.format(url) # initialize try: l = ldap.initialize(url) except ldap.LDAPError as ldaperror: print 'initialize() failed: {0} - {1}'.format(url, ldaperror) else: print 'initialize() succeeded: {0}'.format(url) # bind try: l.simple_bind_s(binddn, bindpw) except ldap.LDAPError as ldaperror: print 'bind failed: {0}'.format(ldaperror) else: print 'bind succeeded' print "" -->snap - Code<-- This seems to happen, because python-ldap doesn't use dn2domain() and domain2hostlist() from libldap. See also the following IRC log where OpenLDAP dev 'hyc' pointed me towards this: -->snip - IRC-Log<-- I'm using python-ldap but it seems to be unable to do SRV lookups when using an URI like ldap:///dc=company,dc=tld although it validates the URI just fine using ldapurl.isLDAPUrl() does anyone know whether there are known issues with python-ldap and doing SRV lookups? a manual 'ldapsearch' using this URI works just fine, so it doesn't seem to be an issue with my OpenLDAP libs but actually an issue of python-ldap itself? ;-( dunno anything about how python-ldap works seems like you need a python-specific channel, not #openldap ok, ldapsearch actually just takes the URLencoded representation of said URI, but even this one doesn't work in python-ldap? hyc: yes, maybe? is python-ldap pure python? or does it just use libldap underneath? hyc: when I looked at it, it linked to libldap hyc: it uses libldap hyc: from the python-ldap README: "[?] Mainly it wraps the OpenLDAP client libs for that purpose." eliasp: ok. should note, libldap doesn't do SRV processing. the OpenLDAP cmdline tools do it themselves hyc: meh, ok? that explains a lot ;) since the behavior is not part of the C API spec, we didn't move it into there hyc: any chance on doing this in libldap at some point? ok it would be a major behavior change, I think no. currently ldap:/// always means localhost. lots of things would break if it turned into an automatic DNS lookup so there's actually no way to make use of SRV records outside the cli tools (besides manually decomposing the URI and doing a manual SRV lookup based on the URI structure)? pretty much hyc: hmm, ok? well, looks like I got to spend some more hours on implementing this then in my module? :) hyc: anyways, thanks a lot for the information eliasp: at least you can look at the code in openldap clients/tools as a model hyc: I definitely will? the bits you need are implemented in libldap, e.g. ldap_dn2domain and ldap_domain2hostlist so it shouldn't be too tough hyc: ok, looking at it now -->snap - IRC-Log<-- So I'm wondering whether it would be possible to add support for doing this in python-ldap by using the said functions in libldap? Otherwise I think such URLs shouldn't be validated successfully, as they obviously can't be used to bind. Best regards and thanks a lot for all the work on python-ldap! - Elias P. P.S. Using: - Python 2.7.5 - python-ldap-2.4.13 - openldap-2.4.35 - Binding to ActiveDirectory (2008) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 263 bytes Desc: OpenPGP digital signature URL: From michael at stroeder.com Wed Oct 16 09:25:59 2013 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Wed, 16 Oct 2013 09:25:59 +0200 Subject: [python-ldap] Validated URL can't be used for bind - handling SRV lookups In-Reply-To: <525DC2BB.3090408@eliasprobst.eu> References: <525DC2BB.3090408@eliasprobst.eu> Message-ID: <525E3F87.7060403@stroeder.com> Elias Probst wrote: > I planned to make it possible to use URLs like this: > ldap:///dc=company,dc=tld You should seriously consider the security implications regarding DNS spoofing by relying on yet another DNS lookup which is *not* protected by e.g. TLS hostname check. > When using such an URL on the commandline (e.g. ldapsearch) this will > cause a DNS lookup to retrieve SRV records from DNS contining pointers > to LDAP hosts and their ports which will then be used to bind to. Yes, as Howard pointed out that's a feature of the command-line tools. > python-ldap validates such an URL just fine using ldapurl.isLDAPUrl(), > but actually using in in ldap.initialize() will fail. > [..] > initialize() failed: ldap:///dc=institution,dc=de - (2, 'No such file or > directory') Yes. > This seems to happen, because python-ldap doesn't use dn2domain() and > domain2hostlist() from libldap. See also the following IRC log where > OpenLDAP dev 'hyc' pointed me towards this: So what do you expect python-ldap to do? Mainly you have to implement that yourself by using one of the DNS modules for Python (like I did in web2ldap). It's not a big deal anyway. But again: Think twice considering security aspects. 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 mail at eliasprobst.eu Wed Oct 16 18:02:36 2013 From: mail at eliasprobst.eu (Elias Probst) Date: Wed, 16 Oct 2013 18:02:36 +0200 Subject: [python-ldap] Validated URL can't be used for bind - handling SRV lookups References: <525DC2BB.3090408@eliasprobst.eu> <525E3F87.7060403@stroeder.com> Message-ID: <525EB89C.5050906@eliasprobst.eu> On 16.10.2013 09:25, Michael Str?der wrote: > Elias Probst wrote: >> I planned to make it possible to use URLs like this: >> ldap:///dc=company,dc=tld > You should seriously consider the security implications regarding DNS spoofing > by relying on yet another DNS lookup which is *not* protected by e.g. TLS > hostname check. So is the first lookup. Either I use DNSSEC/only IPs or any of my DNS queries could be forged. > [?] >> This seems to happen, because python-ldap doesn't use dn2domain() and >> domain2hostlist() from libldap. See also the following IRC log where >> OpenLDAP dev 'hyc' pointed me towards this: > So what do you expect python-ldap to do? I expected python-ldap to handle such URLs just like 'ldapsearch' does without any additional implementation to handle SRV lookups manually. > Mainly you have to implement that yourself by using one of the DNS modules for > Python (like I did in web2ldap). It's not a big deal anyway. Just looked briefly at the code and it seems to be rather straightforward. I'll have to re-implement it (instead of copying) though, as the GPLv2 isn't compatible with the Apache License used by Salt. > But again: Think twice considering security aspects. Yes, I'll surely do. Maybe I'll add some warnings in case SRV is used to the log output. In my use case, I'm fine with using it this way. > Ciao, Michael. Thanks a lot for the input! Elias P. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 263 bytes Desc: OpenPGP digital signature URL: From raphael.barrois at polytechnique.org Thu Nov 14 10:57:06 2013 From: raphael.barrois at polytechnique.org (=?UTF-8?B?UmFwaGHDq2w=?= Barrois) Date: Thu, 14 Nov 2013 10:57:06 +0100 Subject: [python-ldap] Yet another Python3 port Message-ID: <20131114105706.14b0adae@ithor> Hi there, I've been working on a backwards-compatible, single-codebase port of python-ldap to Python3. The current status can be seen here: https://github.com/rbarrois/python-ldap/tree/py3 (I've gitified the CVS history). The test suite appears to run (apart from one test that was already broken before my changes). Before I continue working on this port, I'd like to hear from the python-ldap community: * Does this port interest you? * The test suite looks small and short; have I overlooked a more comprehensive test suite? Thanks! -- Rapha?l Barrois From gustavo.gomez at nuevosmedios.ws Fri Nov 15 18:13:19 2013 From: gustavo.gomez at nuevosmedios.ws (=?ISO-8859-1?Q?Gustavo_G=F3mez?=) Date: Fri, 15 Nov 2013 12:13:19 -0500 Subject: [python-ldap] Connection to Active Directory Message-ID: Hello, I am trying to authenticate against an Active Directory. If I use a tool like Apache Directory Studio it works if I pass as the user the string "DOMAIN\myuser", but I need to know how can I can connect using Python. It does not work if I use "cn=myuser,dc=domain,dc=com". On Python, if I pass "DOMAIN\myuser" I get: ldap.FILTER_ERROR: {'desc': 'Bad search filter'} Otherwise, I get: {'info': '80090308: LdapErr: DSID-0C0903AA, comment: AcceptSecurityContext error, data 525, v1772', 'desc': 'Invalid credentials'} I am trying the following script: # ----- import ldap conn = ldap.initialize("ldap://server:389") try: conn.set_option(ldap.OPT_REFERRALS, 0) conn.simple_bind_s('myuser', 'mypass') conn.search_st('DC=domain,DC=com', ldap.SCOPE_SUBTREE, "(uid=%(user)s)") except ldap.INVALID_CREDENTIALS as e: print 'wrong password provided' # ----- Any idea? -- *Gustavo G?mez Farhat* Ingeniero de Desarrollo e Implementaci?n * * +(57)(2)3809490-4850745 3165097806 Cali, Colombia gustavo.gomez at nuevosmedios.ws -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at eliasprobst.eu Fri Nov 15 21:27:52 2013 From: mail at eliasprobst.eu (Elias Probst) Date: Fri, 15 Nov 2013 21:27:52 +0100 Subject: [python-ldap] Connection to Active Directory References: Message-ID: <528683C8.3060205@eliasprobst.eu> On 15.11.2013 18:13, Gustavo G?mez wrote: > Hello, I am trying to authenticate against an Active Directory. If I > use a tool like Apache Directory Studio it works if I pass as the user > the string "DOMAIN\myuser", but I need to know how can I can connect > using Python. It does not work if I use "cn=myuser,dc=domain,dc=com". > > On Python, if I pass "DOMAIN\myuser" I get: ldap.FILTER_ERROR: > {'desc': 'Bad search filter'} > > Simply try user at domain - Elias -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 263 bytes Desc: OpenPGP digital signature URL: From mail at eliasprobst.eu Fri Nov 15 21:25:57 2013 From: mail at eliasprobst.eu (Elias Probst) Date: Fri, 15 Nov 2013 21:25:57 +0100 Subject: [python-ldap] Connection to Active Directory References: Message-ID: <52868355.1050800@eliasprobst.eu> On 15.11.2013 18:13, Gustavo G?mez wrote: > Hello, I am trying to authenticate against an Active Directory. If I > use a tool like Apache Directory Studio it works if I pass as the user > the string "DOMAIN\myuser", but I need to know how can I can connect > using Python. It does not work if I use "cn=myuser,dc=domain,dc=com". > > On Python, if I pass "DOMAIN\myuser" I get: ldap.FILTER_ERROR: > {'desc': 'Bad search filter'} Simply try user at domain - Elias -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 263 bytes Desc: OpenPGP digital signature URL: From mailinglist0 at skurfer.com Mon Nov 18 14:58:36 2013 From: mailinglist0 at skurfer.com (Rob McBroom) Date: Mon, 18 Nov 2013 08:58:36 -0500 Subject: [python-ldap] Yet another Python3 port In-Reply-To: <20131114105706.14b0adae@ithor> References: <20131114105706.14b0adae@ithor> Message-ID: On 14 Nov 2013, at 4:57, Rapha?l Barrois wrote: > Does this port interest you? Yes. I mean, sooner or later, we?re all going to have to be interested, right? -- Rob McBroom http://www.skurfer.com/ From raphael.barrois at m4x.org Mon Nov 18 21:20:59 2013 From: raphael.barrois at m4x.org (=?UTF-8?B?UmFwaGHDq2w=?= Barrois) Date: Mon, 18 Nov 2013 21:20:59 +0100 Subject: [python-ldap] Yet another Python3 port In-Reply-To: References: <20131114105706.14b0adae@ithor> Message-ID: <20131118212059.289877e6@anoth> On Mon, 18 Nov 2013 08:58:36 -0500 "Rob McBroom" wrote: > On 14 Nov 2013, at 4:57, Rapha?l Barrois wrote: > > > Does this port interest you? > > Yes. I mean, sooner or later, we?re all going to have to be interested, right? > Great! Now, let's get to the actual porting issue on which I'd like to get some input. The current python-ldap lib (without my fixes) uses only "str" (or "bytes") internally ? the calling code should perform the "unicode to utf-8" conversion before sending anything, and the reverse when reading. This is quite cumbersome for non-pure-ascii systems (e.g, outside the US), but works not too bad for most commands where lookups, filters, etc. are pure ascii and thus silently converted into utf-8 bytes (as requested per the LDAP RFCs). With Python3, there is no auto-magic str/bytes conversion; we'll have to choose the behaviour regarding input *and* output: 1. Accept only Bytes, return only Bytes 2. Accept both Bytes and Text (with auto-magic cast, as in Py2), return Bytes (as in Py2) 2. Accept both Bytes and Text (with auto-magic cast, as in Py2), return Text 3. Accept only Text, return Text All solutions are possible, the main issue is for users of the library. Here is an example of the same Py2 snippet with the various options, on Py3: >>> print(connection.search_st(filter=u"Rapha?l Barrois".encode('utf-8'))[0]['givenName'][0].decode('utf-8')) u"Rapha?l Barrois" Option 1: --------- >>> print(connection.search_st(filter="Rapha?l Barrois".encode('utf-8'))[0][b'givenName'][0].decode('utf-8')) "Rapha?l Barrois" # NB: We'll have to put a 'b' in front of each attribute name... Option 2: --------- >>> print(connection.search_st(filter="Rapha?l Barrois")[0][b'givenName'][0].decode('utf-8')) "Rapha?l Barrois" # Asymmetrical: we send text, and get bytes # We need to put a 'b' in front of each attribute name... Option 3: --------- >>> print(connection.search_st(filter="Rapha?l Barrois")[0]['givenName'][0]) "Rapha?l Barrois" # Not backwards compatible with Py2, where we'd receive bytes Option 4: --------- >>> print(connection.search_st(filter="Rapha?l Barrois")[0]['givenName'][0]) "Rapha?l Barrois" I personally find the 4th option the cleanest, but it would break compatibility with Py2. What do you think? -- Rapha?l Barrois From d.bajal at hostcomm.ru Tue Nov 19 13:37:06 2013 From: d.bajal at hostcomm.ru (=?UTF-8?B?0JHQsNC20LDQuyDQlNC80LjRgtGA0LjQuQ==?=) Date: Tue, 19 Nov 2013 16:37:06 +0400 Subject: [python-ldap] Yet another Python3 port In-Reply-To: <20131118212059.289877e6@anoth> References: <20131114105706.14b0adae@ithor> <20131118212059.289877e6@anoth> Message-ID: <528B5B72.7070700@hostcomm.ru> 19.11.2013 00:20, Rapha?l Barrois wrote: > 2. Accept both Bytes and Text (with auto-magic cast, as in Py2), > return Text Option 3: For me it would be the best solution because of it's comfort. But I think it is not acceptable for python community because of ambiguous logic. In my opinion the right solution is accept str only, and return str only for py3 users, as well as for py2. The rest job is done by language itself. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 3744 bytes Desc: ?????????????????????????????????? ?????????????? S/MIME URL: From python3ldap at gmail.com Tue Nov 19 13:46:12 2013 From: python3ldap at gmail.com (python3ldap) Date: Tue, 19 Nov 2013 13:46:12 +0100 Subject: [python-ldap] Yet another Python3 port (Rapha?l Barrois) Message-ID: Hi Raphael, I've developed a pure python3 ldap client (can be used with python2 too) that doesn't need the openldap client extension. You can find it on https://pypi.python.org/pypi/python3-ldap. I had the same problem with unicode, in python3 you don't have to care too much about it, but for python2 code I left out the byte->unicode conversion for now, because I'm not sure which is a valid approach to the problem. I've kept the code as clean of as possible without any "if python3 ... else... ", so I have a single codebase to manage. Let me know if you find a valid solution for python2 and python3 "coexistence". Bye, Giovanni On Mon, 18 Nov 2013 08:58:36 -0500 "Rob McBroom" wrote: > On 14 Nov 2013, at 4:57, Rapha?l Barrois wrote: > > > Does this port interest you? > > Yes. I mean, sooner or later, we?re all going to have to be interested, right? > Great! Now, let's get to the actual porting issue on which I'd like to get some input. The current python-ldap lib (without my fixes) uses only "str" (or "bytes") internally ? the calling code should perform the "unicode to utf-8" conversion before sending anything, and the reverse when reading. This is quite cumbersome for non-pure-ascii systems (e.g, outside the US), but works not too bad for most commands where lookups, filters, etc. are pure ascii and thus silently converted into utf-8 bytes (as requested per the LDAP RFCs). With Python3, there is no auto-magic str/bytes conversion; we'll have to choose the behaviour regarding input *and* output: 1. Accept only Bytes, return only Bytes 2. Accept both Bytes and Text (with auto-magic cast, as in Py2), return Bytes (as in Py2) 2. Accept both Bytes and Text (with auto-magic cast, as in Py2), return Text 3. Accept only Text, return Text All solutions are possible, the main issue is for users of the library. Here is an example of the same Py2 snippet with the various options, on Py3: >>> print(connection.search_st( filter=u"Rapha?l Barrois".encode('utf-8'))[0]['givenName'][0].decode('utf-8')) u"Rapha?l Barrois" Option 1: --------- >>> print(connection.search_st(filter="Rapha?l Barrois".encode('utf-8'))[0][b'givenName'][0].decode('utf-8')) "Rapha?l Barrois" # NB: We'll have to put a 'b' in front of each attribute name... Option 2: --------- >>> print(connection.search_st(filter="Rapha?l Barrois")[0][b'givenName'][0].decode('utf-8')) "Rapha?l Barrois" # Asymmetrical: we send text, and get bytes # We need to put a 'b' in front of each attribute name... Option 3: --------- >>> print(connection.search_st(filter="Rapha?l Barrois")[0]['givenName'][0]) "Rapha?l Barrois" # Not backwards compatible with Py2, where we'd receive bytes Option 4: --------- >>> print(connection.search_st(filter="Rapha?l Barrois")[0]['givenName'][0]) "Rapha?l Barrois" I personally find the 4th option the cleanest, but it would break compatibility with Py2. What do you think? -- Rapha?l Barrois From michael at stroeder.com Sat Nov 23 15:19:12 2013 From: michael at stroeder.com (=?windows-1252?Q?Michael_Str=F6der?=) Date: Sat, 23 Nov 2013 15:19:12 +0100 Subject: [python-ldap] Patch for ReconnectLDAPObject In-Reply-To: <05BF9838-2D85-4671-A548-3C6865C77603@giannuzzi.be> References: <76FA2A1C-BC29-4A98-8F84-C7C6E00A08BC@pretaweb.com> <3A9F249B-ED82-4EBB-9315-3D300EAF3E0E@giannuzzi.be> <44A4A60B-A03F-4B1B-83AE-A441797C99BC@giannuzzi.be> <521FBEFB.1030505@stroeder.com> <05BF9838-2D85-4671-A548-3C6865C77603@giannuzzi.be> Message-ID: <5290B960.2040202@stroeder.com> Jonathan Giannuzzi wrote: > Michael Str?der wrote: > >> Jonathan Giannuzzi wrote: >>> Dylan Jay wrote: >>>> This patch seems to work really well. Any chance of getting it included in a release? >>> >>> What is your view on this patch? >> >> It's on my to-do list to carefully look at it. Maybe during the next days... >> >>> Are there any specific issues preventing it from getting merged? >> >> Hmm, in former times there were Python installations built without threading >> support. So I'm a bit cautious regarding backward compability. > > I was using dummy_threading as a fallback for Python installations built without threading, which was introduced in Python 2.3. > On top of that, I was using the PEP8-compliant API (thus no camelCase) which was introduced in Python 2.6. > > In order to be more compatible, I changed the patch to use a dummy condition instead of dummy_threading (similar to DummyLock in ldap/__init__.py) > I also changed it to use the camelCase threading API. > > AFAIK, it should work against Python >= 1.5.1, with or without threads. > I tested it against Python 2.5 (threads), 2.6 (threads and no threads) and 2.7 (threads and no threads). > Unfortunately I don't have easy access to older installations of Python. I've committed a slightly other approach using ldap.LDAPLock class. The most important point is the try-finally-statement within method ReconnectLDAPObject.reconnect() to be sure that the lock gets released if anything goes wrong therein. Please test the CVS version and let me know whether you think something's missing. 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 Sat Nov 23 15:56:05 2013 From: michael at stroeder.com (=?UTF-8?B?TWljaGFlbCBTdHLDtmRlcg==?=) Date: Sat, 23 Nov 2013 15:56:05 +0100 Subject: [python-ldap] Yet another Python3 port In-Reply-To: <528B5B72.7070700@hostcomm.ru> References: <20131114105706.14b0adae@ithor> <20131118212059.289877e6@anoth> <528B5B72.7070700@hostcomm.ru> Message-ID: <5290C205.9010602@stroeder.com> ????? ??????? wrote: > 19.11.2013 00:20, Rapha?l Barrois wrote: >> 2. Accept both Bytes and Text (with auto-magic cast, as in Py2), return Text >> Option 3: > For me it would be the best solution because of it's comfort. > But I think it is not acceptable for python community because of ambiguous logic. > In my opinion the right solution is accept str only, and return str only for > py3 users, as well as for py2. The rest job is done by language itself. Hmm, yes, it's not a matter of comfort. One has to rather decide whether it's possible in general. 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 Sat Nov 23 16:16:30 2013 From: michael at stroeder.com (=?UTF-8?B?TWljaGFlbCBTdHLDtmRlcg==?=) Date: Sat, 23 Nov 2013 16:16:30 +0100 Subject: [python-ldap] Yet another Python3 port In-Reply-To: <20131118212059.289877e6@anoth> References: <20131114105706.14b0adae@ithor> <20131118212059.289877e6@anoth> Message-ID: <5290C6CE.4070504@stroeder.com> Rapha?l Barrois wrote: > The current python-ldap lib (without my fixes) uses only "str" (or "bytes") > internally ? the calling code should perform the "unicode to utf-8" conversion > before sending anything, and the reverse when reading. > > This is quite cumbersome for non-pure-ascii systems (e.g, outside the US), but > works not too bad for most commands where lookups, filters, etc. are pure ascii > and thus silently converted into utf-8 bytes (as requested per the LDAP RFCs). No application should ever rely on automatic string coercion when using python-ldap! I even considered adding assertions making clear that Unicode strings are not allowed. For Python 2 I'd just like to keep things as they are. > With Python3, there is no auto-magic str/bytes conversion; we'll have to choose the behaviour regarding input *and* output: > 1. Accept only Bytes, return only Bytes > 2. Accept both Bytes and Text (with auto-magic cast, as in Py2), return Bytes (as in Py2) > 2. Accept both Bytes and Text (with auto-magic cast, as in Py2), return Text > 3. Accept only Text, return Text Auto-magic casting costs performance. Hint: Personally I'm sometimes using python-ldap for load-testing. And as said numerous times: The goal for a Python3 module is not strict backwards compability because the calling applications have to be changed/re-written anyway. The underlying C code is really cumbersome. So it would be my preference to maintain that for Python 2 *and* 3 in a single code base. Then implement different APIs by stacking wrapper classes on top of byte-oriented _ldap doing the Py2 or Py3 specific stuff. I'd accept an LDAP API for Python 3 which accepts and returns Unicode strings for data for which *always* an (UTF-8) LDAP string representation is used: Distinguished Names LDAP filters SASL strings Attribute type names LDAP URLs compliant LDIF strings Note that some old legacy LDAPv2 servers does not use UTF-8! Some counter examples likely not obvious for most readers here: Attribute values `cred' for simple bind For LDAPv3 extended controls and operations one would have to decide for each special case. 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 Sat Nov 23 16:18:15 2013 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Sat, 23 Nov 2013 16:18:15 +0100 Subject: [python-ldap] Yet another Python3 port (Rapha?l Barrois) In-Reply-To: References: Message-ID: <5290C737.20400@stroeder.com> python3ldap wrote: > I've developed a pure python3 ldap client (can be used with python2 > too) that doesn't need the openldap client extension. You can find it > on https://pypi.python.org/pypi/python3-ldap. Looks interesting. But I wonder how you deal with SSL/TLS and SASL. 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 python3ldap at gmail.com Sat Nov 23 20:22:54 2013 From: python3ldap at gmail.com (python3ldap) Date: Sat, 23 Nov 2013 20:22:54 +0100 Subject: [python-ldap] Yet another Python3 port (Rapha?l Barrois) In-Reply-To: <5290C737.20400@stroeder.com> References: <5290C737.20400@stroeder.com> Message-ID: Hello Michael, I've tried to keep the library simple and consistent with the RFCs. To start an LDAP connection you create a Server object and one (or more) Connection object. In the Server object you specify the communication parameters: from ldap3 import Server, Connection, Tls server = Server('servername') # define an unsecure LDAP server with default parameters (port 389) If you want a SSL connection just add useSsl=True and port=portNnumber and a Tls object to the server definition: server = Server('servername', port = 636, useSsl = True, tls = Tls()) # define a secure (over SSL) LDAP server with default Tls then create the connection object specifying the authentication parameters: connection = Connection(server, user = 'test-user', password = 'test-password') # create a connection to the server (default to simple authentication and synchronous communication strategy) then use the connection as usual: connection.open() connection.bind() results = connection.search(...) connection.close() To start a TLS connection with the StartTLS extension (on an already created unsecure connection) you need a Tls object, if not already passed to the server object: connection.tls = Tls() RFCs specify that Tls can be started either before or after bind: before bind: connection.open() connection.startTls() connection.bind() after bind: connection.open() connection.bind() connection.startTls() The same Tls object is used in SSL connection and startTls operation. It's quite complex because you have to define the needed tls parameters to have a validated connection: localPrivateKeyFile = None, localCertificateFile = None, validate = ssl.CERT_NONE, version = ssl.PROTOCOL_TLSv1, caCertsFile = None Internally, in the Tls object, I use the ssl package of the Python standard library (present in Python2.6, 2.7, and 3.x). I wrap and unwrap the network socket to add and remove the secure layer as needed by the connection: def wrapSocket(self, sock, doHandshake = False): """ Add TLS to a plain socket and return the SSL socket """ return ssl.wrap_socket(sock, keyfile = self.privateKeyFile, certfile = self.certificateFile, server_side = False, cert_reqs = self.validate, ssl_version = self.version, ca_certs = self.caCertsFile, do_handshake_on_connect = doHandshake) @staticmethod def unwrapSocket(sock): """ Remove TLS from an SSL socket and return the plain socket """ return sock.unwrap() For SASL I've developed a ldap3.protocol.sasl package that follow the SaslPrep alghoritm as per RFC 4013 and a generic implementation for EXTERNAL. Now I'm working on MD5 (even if this is deprecated in RFC6331) and I'm not sure what other mechanism should be implemented. That's all. Ciao, Giovanni 2013/11/23 Michael Str?der : > python3ldap wrote: >> I've developed a pure python3 ldap client (can be used with python2 >> too) that doesn't need the openldap client extension. You can find it >> on https://pypi.python.org/pypi/python3-ldap. > > Looks interesting. But I wonder how you deal with SSL/TLS and SASL. > > Ciao, Michael. > From avner.goncalves at s2it.com.br Wed Nov 27 19:16:50 2013 From: avner.goncalves at s2it.com.br (=?iso-8859-1?Q?Avner_Gon=E7alves?=) Date: Wed, 27 Nov 2013 18:16:50 +0000 Subject: [python-ldap] Help for get exception Message-ID: <354FDBD9659C884FA48613BC22DB1AC5C69157@BL2PRD8010MB481.lamprd80.prod.outlook.com> Hello, I run this command in line for terminar: "ldapwhoami -x -D "cn=XXXXXX,ou=People,dc=XXXXXX,dc=com" -e ppolicy -w XXXXXX" Return: "ldap_bind: Invalid credentials (49); Password expired" I need run this code: try: l = ldap.open("127.0.0.1") l.protocol_version = ldap.VERSION3 username = "cn=XXXXXX,ou=People,dc=XXXXXX,dc=com" password = "XXXXXX" msgid = l.simple_bind_s(username,password) print msgid; except ldap.LDAPError, e: print 'Simple bind failed:',str(e) sys.exit(1) And return: "Simple bind failed: {'desc': 'Invalid credentials'}" How i get this execption "Password expired" ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at stroeder.com Wed Nov 27 19:39:29 2013 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Wed, 27 Nov 2013 19:39:29 +0100 Subject: [python-ldap] Help for get exception In-Reply-To: <354FDBD9659C884FA48613BC22DB1AC5C69157@BL2PRD8010MB481.lamprd80.prod.outlook.com> References: <354FDBD9659C884FA48613BC22DB1AC5C69157@BL2PRD8010MB481.lamprd80.prod.outlook.com> Message-ID: <52963C61.5000309@stroeder.com> Avner Gon?alves wrote: > I run this command in line for terminar: > "ldapwhoami -x -D "cn=XXXXXX,ou=People,dc=XXXXXX,dc=com" -e ppolicy -w XXXXXX" > > Return: > "ldap_bind: Invalid credentials (49); Password expired" > > I need run this code: > > try: > l = ldap.open("127.0.0.1") > l.protocol_version = ldap.VERSION3 > > username = "cn=XXXXXX,ou=People,dc=XXXXXX,dc=com" > password = "XXXXXX" > > msgid = l.simple_bind_s(username,password) > print msgid; > > except ldap.LDAPError, e: > print 'Simple bind failed:',str(e) > sys.exit(1) > > And return: > "Simple bind failed: {'desc': 'Invalid credentials'}" > > > How i get this execption "Password expired" ? See Demo/pyasn1/ppolicy.py in python-ldap's source distribution tar.gz. 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 Thu Nov 28 09:38:55 2013 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Thu, 28 Nov 2013 09:38:55 +0100 Subject: [python-ldap] RES: Help for get exception In-Reply-To: <354FDBD9659C884FA48613BC22DB1AC5C69171@BL2PRD8010MB481.lamprd80.prod.outlook.com> References: <354FDBD9659C884FA48613BC22DB1AC5C69157@BL2PRD8010MB481.lamprd80.prod.outlook.com>, <52963C61.5000309@stroeder.com> <354FDBD9659C884FA48613BC22DB1AC5C69171@BL2PRD8010MB481.lamprd80.prod.outlook.com> Message-ID: <5297011F.1060709@stroeder.com> Avner Gon?alves wrote: > Now I'm using the same code "Demo/pyasn1/ppolicy.py", the "timeBeforeExpiration" and "graceAuthNsRemaining" are working perfectly, but when the password expires or the user is locked it back to return the exception of "INVALIDA_CREDENTIALS". > > I can return an exception where I can identify that the User is expired or locked. Ah, sorry, I forgot: This is a deficiency of current python-ldap. It's not possible to receive response control which were attached to an LDAP result message with resultCode!=0. If anybody with C skills wants to look into that... 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 mupendra47 at gmail.com Mon Dec 9 18:52:17 2013 From: mupendra47 at gmail.com (upendra moturi) Date: Mon, 9 Dec 2013 23:22:17 +0530 Subject: [python-ldap] Change password with consideration of pwdInHistory Message-ID: Hi, I have configured pwdInHistory=3 and able to see encrypted values of password,but not able to impose policy to not to use last 3 passwords while changing password. used passwd_s and passwd,but no luck Please help me Regards, Upendra -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at stroeder.com Mon Dec 9 22:00:28 2013 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Mon, 09 Dec 2013 22:00:28 +0100 Subject: [python-ldap] Change password with consideration of pwdInHistory In-Reply-To: References: Message-ID: <52A62F6C.6000705@stroeder.com> upendra moturi wrote: > I have configured pwdInHistory=3 and able to see encrypted values of > password,but not able to impose policy to not to use last 3 passwords while > changing password. > > used passwd_s and passwd,but no luck Behaviour of LDAP servers can be quite different. Which LDAP server is that? Did you configure password policy at the server? Are you sure the configured password policy cleanly applies to the LDAP entry you want to change the password for? 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 nyasha.chigwamba at voss-solutions.com Wed Dec 11 11:31:52 2013 From: nyasha.chigwamba at voss-solutions.com (Nyasha Chigwamba) Date: Wed, 11 Dec 2013 12:31:52 +0200 Subject: [python-ldap] Does python-ldap support IPv6 Message-ID: Hi, As far as I can tell, python-ldap wraps OpenLDAP, which in turn supports IPv6. Therefore, we python-ldap supports IPv6. Is this correct? Regards, Nyasha -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at stroeder.com Thu Dec 12 09:46:19 2013 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Thu, 12 Dec 2013 09:46:19 +0100 Subject: [python-ldap] Does python-ldap support IPv6 In-Reply-To: References: Message-ID: <52A977DB.40702@stroeder.com> Nyasha Chigwamba wrote: > As far as I can tell, python-ldap wraps OpenLDAP, which in turn supports > IPv6. Therefore, we python-ldap supports IPv6. Is this correct? Should work. But why don't you just try yourself? 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 pgadmin at pse-consulting.de Wed Dec 18 11:27:27 2013 From: pgadmin at pse-consulting.de (Andreas Pflug) Date: Wed, 18 Dec 2013 11:27:27 +0100 Subject: [python-ldap] HOW-TO python-ldap installation on Mac OSX Message-ID: <52B1788F.2070900@pse-consulting.de> There's only vague and outdated advice for python-ldap installation on Mac OSX on the http://www.python-ldap.org/download.shtml page, so here my description how to do this. Please include it on the download page. This is working on 10.9 Mavericks, and AFAIR it was the same on 10.8 Mountain Lion. - Install XCode from Apple App Store - From a command line, run xcode-select --install (and aknowledge the command line tools installation) sudo easy_install pip sudo pip install python-ldap After a major OS upgrade (e.g. 10.8->10.9), you'd have to repeat the procedure. Regards, Andreas From sebbydlx at yahoo.com Mon Dec 30 15:30:51 2013 From: sebbydlx at yahoo.com (Sebastian Brause) Date: Mon, 30 Dec 2013 14:30:51 +0000 (GMT) Subject: [python-ldap] SASL + REALM Message-ID: <1388413851.30325.YahooMailNeo@web28702.mail.ir2.yahoo.com> Hi, 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'} That's strange because the OpenLDAP tools work fine (on the same system - so, there are no connection problems, wrong user/password, no certificate issues, etc...) This works pretty well: ldapsearch -v -H ldaps://ldapsrv.mydomain.local:60000 -Y DIGEST-MD5 -U "ldapadmin-222" -X "ldapadmin-222" -R "company" "DC=mydomain,DC=local" "cn=*" So, I don't know what's wrong with my code. I tried it with the current version (python-ldap 2.4.14) and 2.3.10 Thanks for your help in advance. Kind regards, Seb