From python3ldap at gmail.com Sun Jan 5 15:19:51 2014 From: python3ldap at gmail.com (python3ldap) Date: Sun, 5 Jan 2014 15:19:51 +0100 Subject: [python3-ldap] python3-ldap 0.7.3 released! Message-ID: Hello everybody, I've released the 0.7.3 version of python3-ldap which implements the SASL DIGEST-MD5 authentication mechanism. Even if DIGEST-MD5 is deprecated by RFC 6331 that clearly states that SASL DIGEST-MD5 is an insecure and unsuitable mechanism for use in protocols, marks it as OBSOLETE in the IANA Registry of SASL mechanisms and moves RFC 2831 to Historic status I've developed the authentication phase of the protocol because it is still used in ldap servers. To use the DIGEST-MD5 you must pass a 4-value tuple as saslCredentials: (realm, user, password, authzId). You can pass None for realm and authzId if they are not used. Quality of Protection is always 'auth': server = Server(host = test_server, port = test_port) connection = Connection(server, autoBind = True, version = 3, clientStrategy = test_strategy, authentication = AUTH_SASL, saslMechanism = 'DIGEST-MD5', saslCredentials = (None, 'username', 'password', None)) Username is not required to be an ldap entry, but it can be any identifier recognized by the server (i.e. email, principal). If you pass None as realm the default realm of the server will be used. There is also a minor bug fix when using parentheses as characters of search filter (thanks jeph). Again keep in mind that DIGEST-MD5 is deprecated and should not be used Happy New Year, gc From mr.gary.waters at gmail.com Mon Feb 3 22:43:21 2014 From: mr.gary.waters at gmail.com (Gary Waters) Date: Mon, 03 Feb 2014 13:43:21 -0800 Subject: [python3-ldap] ldap search object Message-ID: <52F00D79.7000809@gmail.com> Hello, When I try to search using getOperationalAttributes=True, I am not getting all the operational attributes, particularly I am interesting in getting nsRoleDN and nsRole. However if I just request nsRoleDN and nsRole (with or without getOperationalAttributes=True) I do see those attributes. I see that in the code the variable ALL_OPERATIONAL_ATTRIBUTES = '+' I am new to this, but when I try this from ldapsearch on the command line I dont see a difference. (where my filter is 'objectclass=* + 'or just objectclass=*) Is this because of my server? Thanks for your help, Gary Ldap3 Version: I am running is from a pip install from a couple of weeks ago. via this - 'pip install python3-ldap' in Ubuntu 13.04 and python 2.7. From mr.gary.waters at gmail.com Mon Feb 3 23:19:41 2014 From: mr.gary.waters at gmail.com (Gary Waters) Date: Mon, 03 Feb 2014 14:19:41 -0800 Subject: [python3-ldap] ldap search object In-Reply-To: <52F00D79.7000809@gmail.com> References: <52F00D79.7000809@gmail.com> Message-ID: <52F015FD.7060707@gmail.com> Hi, Ahh.. I just read this RFC: http://tools.ietf.org/html/rfc3673 Please ignore my previous email. I believe my server is ignoring these Dynamic attributes unless specified. I am going to make a list variabled, called FORCE_ALL_OPERATIONAL_ATTRIBUTES with the following attributes requested: * accountUnlockTime aci attributeTypes copiedFrom copyingFrom createTimestamp creatorsName dITContentRules dITStructureRules dncomp entrydn entryid hasSubordinates ldapSchemas ldapSyntaxes matchingRules matchingRuleUse modifiersName modifyTimestamp nameForms nsAccountLock nsAIMStatusGraphic nsAIMStatusText nsBackendSuffix nscpEntryDN nsds5ReplConflict nsICQStatusGraphic nsICQStatusText nsIdleTimeout nsLookThroughLimit nsRole nsRoleDN nsSchemaCSN nsSizeLimit nsTimeLimit nsUniqueId nsYIMStatusGraphic nsYIMStatusText numSubordinates objectClasses parentid passwordAllowChangeTime passwordExpirationTime passwordExpWarned passwordGraceUserTime passwordHistory passwordRetryCount pwdExpirationWarned pwdGraceUserTime pwdHistory pwdpolicysubentry retryCountResetTime subschemaSubentry vendorName vendorVersion If anyone is interested, I can work it into the ldap3 module and search class. For now I will just put this into my app. - Gary On Mon 03 Feb 2014 01:43:21 PM PST, Gary Waters wrote: > Hello, > > When I try to search using getOperationalAttributes=True, I am not > getting all the operational attributes, particularly I am interesting in > getting nsRoleDN and nsRole. > > However if I just request nsRoleDN and nsRole (with or without > getOperationalAttributes=True) I do see those attributes. > > I see that in the code the variable > ALL_OPERATIONAL_ATTRIBUTES = '+' > > I am new to this, but when I try this from ldapsearch on the command > line I dont see a difference. (where my filter is 'objectclass=* + 'or > just objectclass=*) > > Is this because of my server? > > Thanks for your help, > Gary > > Ldap3 Version: I am running is from a pip install from a couple of weeks > ago. via this - 'pip install python3-ldap' in Ubuntu 13.04 and python 2.7. > From python3ldap at gmail.com Tue Feb 4 16:09:33 2014 From: python3ldap at gmail.com (python3ldap) Date: Tue, 4 Feb 2014 16:09:33 +0100 Subject: [python3-ldap] ldap search object Message-ID: python3ldap python3ldap at gmail.com 09:49 (6 ore fa) a python3-ldap-r. Hello Gary, you're right, RFC3673 define the '+' (plus) as a attribute descriptor for requesting all operational attributes from the DSA (the LDAP server). The problem is that the RFC doesn't enforce the server to really return ALL opeartional attributes. Furthermore each server implementation can decide which attributes are "operational" beside the 'creatorsName', 'createTimestamp', 'modifiersName', and 'modifyTimestamp' the should be defined for all the entries in the ldap database (DIT) as per rfc 4112 (3.4). To check if an attribute is "operational" you can read the schema returned by your DSA, if the attribute "usage" is not "userApplications" it is intended to be an operational attribute, but how this is managed by the DSA is a local (server) matter. I suggest you to add only the attributes you need in the attribute list of the search operation, and treat them as normal (userApplication) attributes. Bye, Giovanni Have fun, gc Have fun, gc From python3ldap at gmail.com Sun Feb 9 22:50:47 2014 From: python3ldap at gmail.com (python3ldap) Date: Sun, 9 Feb 2014 22:50:47 +0100 Subject: [python3-ldap] python3-ldap 0.8.1 released! Message-ID: Hello everybody, I've released the 0.8.1 version of python3-ldap. It include a new package, 'abstraction' with an abstraction layer for LDAP. It's a tools I used on a previous project that I have elaborated to be of more general use, limited to search, for now. WIth the abstraction layer you can specify definition for ldap object and anttributes with pre and post validation at attribute level. You can even dereference an attribute containing a DN with an object of the relevant type. (For example searching for a group you get the 'member' attribute populated with the whole entries of member, not only the DN). It has a simplified query language for writing filters that resemble a dictionary that should be much more simple to use than the LDAP filter syntax. For example to search for a cn of bob or john and a surname starting with 'sm' you could use: 'CommonName: bob;john, Surname:sm*). I find the abstraction layer is quite useful at the interactive prompt, Look at the documentation for a better explanation of its features, and let me know what you think about it. Another feature included in 0.8 is the context manager for the Connection object. Now if you use: with Connection(...) as c: c.search(...) the connection is automatically opened, bound and closed even if you have an exception in the code inside the 'with'. 0.8 includes additional feature/fix, this is from the changelog:: * 0.8,1 - Changed exception returned by the library to LDAPException, a subclass of Exception. * 0.8.0 - 2014.02.08 - Added abstraction layer (for searching) - Added context manager to Connection class - Added readOnly parameter to Connection class - Fixed a bug in search with 'less than' (<=) parameter - Remove validation of available SSL protocols because different Python interpreters can use different ssl packages Have fun, Giovanni From cito at online.de Wed Feb 26 11:55:12 2014 From: cito at online.de (Christoph Zwerschke) Date: Wed, 26 Feb 2014 11:55:12 +0100 Subject: [python3-ldap] Connection pooling Message-ID: <530DC810.7090500@online.de> Hi everybody, as a user of python-ldap I liked the ReconnectLDAPObject and the connection pooling provided by ldappool. Anybody else interested in getting these features into python3-ldap? -- Christoph From python3ldap at gmail.com Wed Feb 26 17:47:20 2014 From: python3ldap at gmail.com (python3ldap) Date: Wed, 26 Feb 2014 17:47:20 +0100 Subject: [python3-ldap] Connection pooling In-Reply-To: <530DC810.7090500@online.de> References: <530DC810.7090500@online.de> Message-ID: Hi Christoph,thanks for your message. I'd like to keep python3-ldap very compliant with the current LDAP RFCs and I don't think that an "auto-reconnect" behaviour is specified in any RFC regarding LDAP. .Anyway the implementation of an "auto-reconnect" flag in the Connection object of python3-ldap should be quite simple, can you tell me what is your expectations for this feature in python3-ldap? Regarding the ldappool feature this could be a helper function in the library, I don't think I should have any problem in developing it. Can you give me any suggestion of what you think should be useful to have in this feature? Bye, Giovanni Have fun, gc 2014-02-26 11:55 GMT+01:00 Christoph Zwerschke : > Hi everybody, > > as a user of python-ldap I liked the ReconnectLDAPObject and the connection > pooling provided by ldappool. > > Anybody else interested in getting these features into python3-ldap? > > -- Christoph > > > > > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap From mr.gary.waters at gmail.com Tue Mar 11 01:14:49 2014 From: mr.gary.waters at gmail.com (Gary Waters) Date: Mon, 10 Mar 2014 17:14:49 -0700 Subject: [python3-ldap] Ldap Add Error Message-ID: <531E5579.4050006@gmail.com> Hi Giovanni, I wrote the ldap cloning script, and it worked great. Thanks to your wonderful working examples. I do have a problem with a 1% of the users I tried to clone this week, and that is I am getting a "Protocol Error", with no message. Here is the method call: dst_result = dst_connection_object.add(dn, 'iNetOrgPerson', src_connection_object.response[0]['attributes']) Here is the full result dict: {'dn': '', 'referrals': None, 'description': 'protocolError', 'result': 2, 'message': '', 'type': 'addResponse'} I am able to create an ldifStream from the response: ldifStream = src_server_conn.responseToLdif() And I able to manually import the ldif just fine. How do I get more information out of the result or is there another method that I could to the connection object that would help me figure out what is wrong with this account ? Thanks for your advise. -Gary From python3ldap at gmail.com Fri Mar 21 00:01:37 2014 From: python3ldap at gmail.com (python3ldap) Date: Fri, 21 Mar 2014 00:01:37 +0100 Subject: [python3-ldap] python3-ldap 0.9.0 is out with a lot of new stuff! Message-ID: Hello everybody, I have made a quite large update to python3-ldap. The main feature is that the library is PEP8 compliance now. This means that I had to change the function and attributes name to follow the naming convention. You should change your code to the new signatures. I'm sorry for that. If you don't want you can find the previous Server and Connection object inthe ldap3.compat package, if you import from that package your code should keep working. Another new feature is the rewritten (with sphinx) library documentation. It's now hosted at http://pythonhosted.org//python3-ldap. I expanded some paragraph to better explain the library use. There is a new 'core' component in the library; ServerPool. It's now possilbe define a pool of server to use with different pooling strategies (active, round robin, random). Each time you open the connection a new server is chosen. This can be helpful if you connect to multi-replica distributed LDAP servers. Another feature is the SyncRestartableStrategy. It's similar to the ReconnectLdap object of python-ldap and can be used with buggy servers because it retries the operation before giving up. Together with the ServerPool can be used in long standing application for High Availability/High Reliability. Thanks to Christoph for requesting this feature. I'm still working on the ConnectionPool. I fixed some minor bugs and made the library works on Python 2.6 too. Thanks to Gary for showing me the problems with 2.6. This is a big update and I must admit that tests don't cover all the new feature, so please let me know if there is any problem with the update. I'll try to fix them as soon as possible. Anyway I'll keep the previous (0.8.3) non PEP8 compliant version available on pypi for a while. This is the changelog: 0.9.0 2014.03.20 PEP8 compliance added ldap3.compat package with non PEP8-compliant signatures renamed ldap3.abstraction to ldap3.abstract moved connection.py, server.py and tls.py files to ldap3.core fixed SyncWaitRestartableStrategy (thanks to Christoph) Server Pools 0.8.3 2014.03.08 SyncWaitRestartable strategy removed forceBind parameter usage statistics updated with restartable successes/failures counters and open/closed/wrapped sockets counter 0.8.2 2014.03.04 Added refresh() method to Entry object to read again the attributes from the Reader Fixed python 2.6 issues Fixed test suite for python 2.6 Have fun, Giovanni From ahydle at gmail.com Fri Mar 21 19:10:28 2014 From: ahydle at gmail.com (Andrew Hydle) Date: Fri, 21 Mar 2014 11:10:28 -0700 Subject: [python3-ldap] Key error help Message-ID: Hi, I am getting a key error when I start looping through c.response. Looking at the data coming out of c.repsonse I am wondering if the dictionary that I am receiving is missing a } I am running python 3.4.0 / python3-ldap 0.9.0 on Windows 7 [{'raw_attributes': {'displayName': [b'First Last'], 'description': [b'LDAP Description']}, 'dn': 'CN=First Last,OU=OU,OU=Users,OU=CITY,OU=company,DC=domain,DC=net', 'type': 'searchResEntry', 'attributes': {'displayName': ['First Last'], 'description': ['LDAP Description']}}, {'uri': ['ldap:// DomainDnsZones.domain.net/DC=DomainDnsZones,DC=domain,DC=net'],'type': 'searchResRef'}, {'uri':['ldap:// ForestDnsZones.domain.net/DC=ForestDnsZones,DC=domain,DC=net'], 'type': 'searchResRef'}, {'uri': ['ldap:// domain.net/CN=Configuration,DC=domain,DC=net'], 'type': 'searchResRef'}] {'displayName': ['First Last'], 'description': ['LDAP Description']} Traceback (most recent call last): File "sapADImport.py", line 31, in print(r['attributes']) KeyError: 'attributes' ------------------------------------------- from ldap3 import Server, Connection from ldap3 import AUTH_SIMPLE, STRATEGY_SYNC, STRATEGY_ASYNC_THREADED, SEARCH_SCOPE_WHOLE_SUBTREE, SEARCH_DEREFERENCE_ALWAYS, GET_ALL_INFO s = Server(args.srvr, port=int(args.sprt), get_info=GET_ALL_INFO) c = Connection(s, auto_bind=True, client_strategy=STRATEGY_SYNC, user=args.user, password=args.pasw, authentication=AUTH_SIMPLE) lfilter = '(&(objectCategory=person)(sAMAccountName=%s))' % uid.lower() result = c.search(search_base=args.bdn, search_filter=lfilter, search_scope=SEARCH_SCOPE_WHOLE_SUBTREE, attributes=['displayName', 'description']) print(c.response) if result: for r in c.response: print(r['attributes']) else: print('result', c.result) -------------- next part -------------- An HTML attachment was scrubbed... URL: From python3ldap at gmail.com Fri Mar 21 20:04:44 2014 From: python3ldap at gmail.com (python3ldap) Date: Fri, 21 Mar 2014 20:04:44 +0100 Subject: [python3-ldap] Key error help In-Reply-To: References: Message-ID: Hello Andrew, there is no } missing, the problem is that your LDAP server returns as second, third and fourth element of the response a Search Result Referral that is a reference to another server: {'uri': ['ldap://DomainDnsZones.domain.net/DC=DomainDnsZones,DC=domain,DC=net'], 'type': 'searchResRef'} {'uri': ['ldap://ForestDnsZones.domain.net/DC=ForestDnsZones,DC=domain,DC=net'], 'type': 'searchResRef'} {'uri': ['ldap://domain.net/CN=Configuration,DC=domain,DC=net'], 'type': 'searchResRef'} and doens't have any attributes. You can try to set the auto_referrals parameter to True in the connection object and specify a list of allowed_referrals_hosts in the Server object (you can set it to '*' to allow all server referred in the response). Let me know if this solve your problem. Bye, Giovanni Have fun, gc 2014-03-21 19:10 GMT+01:00 Andrew Hydle : > Hi, > > I am getting a key error when I start looping through c.response. Looking at > the data coming out of c.repsonse I am wondering if the dictionary that I am > receiving is missing a } > > I am running python 3.4.0 / python3-ldap 0.9.0 on Windows 7 > > [{'raw_attributes': {'displayName': [b'First Last'], 'description': [b'LDAP > Description']}, 'dn': 'CN=First > Last,OU=OU,OU=Users,OU=CITY,OU=company,DC=domain,DC=net', 'type': > 'searchResEntry', 'attributes': {'displayName': ['First Last'], > 'description': ['LDAP Description']}}, {'uri': > ['ldap://DomainDnsZones.domain.net/DC=DomainDnsZones,DC=domain,DC=net'],'type': > 'searchResRef'}, > {'uri':['ldap://ForestDnsZones.domain.net/DC=ForestDnsZones,DC=domain,DC=net'], > 'type': 'searchResRef'}, {'uri': > ['ldap://domain.net/CN=Configuration,DC=domain,DC=net'], 'type': > 'searchResRef'}] > > {'displayName': ['First Last'], 'description': ['LDAP Description']} > Traceback (most recent call last): > File "sapADImport.py", line 31, in > print(r['attributes']) > KeyError: 'attributes' > > ------------------------------------------- > > from ldap3 import Server, Connection > from ldap3 import AUTH_SIMPLE, STRATEGY_SYNC, STRATEGY_ASYNC_THREADED, > SEARCH_SCOPE_WHOLE_SUBTREE, SEARCH_DEREFERENCE_ALWAYS, GET_ALL_INFO > > s = Server(args.srvr, port=int(args.sprt), get_info=GET_ALL_INFO) > c = Connection(s, auto_bind=True, client_strategy=STRATEGY_SYNC, > user=args.user, password=args.pasw, authentication=AUTH_SIMPLE) > > lfilter = '(&(objectCategory=person)(sAMAccountName=%s))' % uid.lower() > result = c.search(search_base=args.bdn, search_filter=lfilter, > search_scope=SEARCH_SCOPE_WHOLE_SUBTREE, attributes=['displayName', > 'description']) > > > print(c.response) > if result: > for r in c.response: > print(r['attributes']) > > else: > print('result', c.result) > > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap > From ahydle at gmail.com Fri Mar 21 21:51:29 2014 From: ahydle at gmail.com (Andrew Hydle) Date: Fri, 21 Mar 2014 13:51:29 -0700 Subject: [python3-ldap] Key error help In-Reply-To: References: Message-ID: Hi Giovanni, I changed that as suggested but unfortunately I still get the same key error: s = Server(args.srvr, port=int(args.sprt), get_info=GET_ALL_INFO, allowed_referral_hosts='*') c = Connection(s, auto_bind=True, client_strategy=STRATEGY_SYNC, user=args.user, password=args.pasw, authentication=AUTH_SIMPLE, auto_referrals=True) Can you think of anything else I could try? Thanks Andrew On Fri, Mar 21, 2014 at 12:04 PM, python3ldap wrote: > Hello Andrew, > there is no } missing, the problem is that your LDAP server returns as > second, third and fourth element of the response a Search Result > Referral that is a reference to another server: > > {'uri': ['ldap:// > DomainDnsZones.domain.net/DC=DomainDnsZones,DC=domain,DC=net'], > 'type': 'searchResRef'} > {'uri': ['ldap:// > ForestDnsZones.domain.net/DC=ForestDnsZones,DC=domain,DC=net'], > 'type': 'searchResRef'} > {'uri': ['ldap://domain.net/CN=Configuration,DC=domain,DC=net'], > 'type': 'searchResRef'} > > and doens't have any attributes. You can try to set the > auto_referrals parameter to True in the connection object and specify > a list of allowed_referrals_hosts in the Server object (you can set it > to '*' to allow all server referred in the response). > > Let me know if this solve your problem. > > Bye, > Giovanni > Have fun, > gc > > > 2014-03-21 19:10 GMT+01:00 Andrew Hydle : > > Hi, > > > > I am getting a key error when I start looping through c.response. > Looking at > > the data coming out of c.repsonse I am wondering if the dictionary that > I am > > receiving is missing a } > > > > I am running python 3.4.0 / python3-ldap 0.9.0 on Windows 7 > > > > [{'raw_attributes': {'displayName': [b'First Last'], 'description': > [b'LDAP > > Description']}, 'dn': 'CN=First > > Last,OU=OU,OU=Users,OU=CITY,OU=company,DC=domain,DC=net', 'type': > > 'searchResEntry', 'attributes': {'displayName': ['First Last'], > > 'description': ['LDAP Description']}}, {'uri': > > ['ldap://DomainDnsZones.domain.net/DC=DomainDnsZones,DC=domain,DC=net' > ],'type': > > 'searchResRef'}, > > {'uri':['ldap:// > ForestDnsZones.domain.net/DC=ForestDnsZones,DC=domain,DC=net'], > > 'type': 'searchResRef'}, {'uri': > > ['ldap://domain.net/CN=Configuration,DC=domain,DC=net'], 'type': > > 'searchResRef'}] > > > > {'displayName': ['First Last'], 'description': ['LDAP Description']} > > Traceback (most recent call last): > > File "sapADImport.py", line 31, in > > print(r['attributes']) > > KeyError: 'attributes' > > > > ------------------------------------------- > > > > from ldap3 import Server, Connection > > from ldap3 import AUTH_SIMPLE, STRATEGY_SYNC, STRATEGY_ASYNC_THREADED, > > SEARCH_SCOPE_WHOLE_SUBTREE, SEARCH_DEREFERENCE_ALWAYS, GET_ALL_INFO > > > > s = Server(args.srvr, port=int(args.sprt), get_info=GET_ALL_INFO) > > c = Connection(s, auto_bind=True, client_strategy=STRATEGY_SYNC, > > user=args.user, password=args.pasw, authentication=AUTH_SIMPLE) > > > > lfilter = '(&(objectCategory=person)(sAMAccountName=%s))' % uid.lower() > > result = c.search(search_base=args.bdn, search_filter=lfilter, > > search_scope=SEARCH_SCOPE_WHOLE_SUBTREE, attributes=['displayName', > > 'description']) > > > > > > print(c.response) > > if result: > > for r in c.response: > > print(r['attributes']) > > > > else: > > print('result', c.result) > > > > _______________________________________________ > > python3-ldap mailing list > > python3-ldap at python.org > > https://mail.python.org/mailman/listinfo/python3-ldap > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jcasale at activenetwerx.com Fri Mar 21 22:50:28 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Fri, 21 Mar 2014 21:50:28 +0000 Subject: [python3-ldap] ServerPool issue Message-ID: Hi Giovanni, Seems check_availability has a syntax error in Server class on line 108, self.server.host... On another note, I am interested in building a wrapper around this to provide some resiliency around a query to a DC in Active Directory whereby there are many and one may not have an object replicated or may be down. I have some ideas on building the class with knowledge of the size of the pool to abstract retries but I am not certain of my connection brokering approach. I don't want to open a connection until a method is invoked after which I will retain the connection instance. This idea worked before I had the potential to pool, but now I am not clear on the most elegant approach. What is your opinion? Thanks, jlc From python3ldap at gmail.com Fri Mar 21 23:05:07 2014 From: python3ldap at gmail.com (Python3-ldap) Date: Fri, 21 Mar 2014 23:05:07 +0100 Subject: [python3-ldap] R: Key error help Message-ID: <532cb79c.86440f0a.4693.fffff326@mx.google.com> This means that the auto_referral is not working for that Uri. Can you tell me the server version you're connecting to? I could try to set up a lab server. In the meanwhile you should repeat the search in the contest specified in the result Uri. Giovanni gc ----- Messaggio originale ----- Da: "Andrew Hydle" Inviato: ?21/?03/?2014 21.51 A: "python3ldap" Cc: "python3-ldap at python.org" Oggetto: Re: [python3-ldap] Key error help Hi Giovanni, I changed that as suggested but unfortunately I still get the same key error: s = Server(args.srvr, port=int(args.sprt), get_info=GET_ALL_INFO, allowed_referral_hosts='*') c = Connection(s, auto_bind=True, client_strategy=STRATEGY_SYNC, user=args.user, password=args.pasw, authentication=AUTH_SIMPLE, auto_referrals=True) Can you think of anything else I could try? Thanks Andrew On Fri, Mar 21, 2014 at 12:04 PM, python3ldap wrote: Hello Andrew, there is no } missing, the problem is that your LDAP server returns as second, third and fourth element of the response a Search Result Referral that is a reference to another server: {'uri': ['ldap://DomainDnsZones.domain.net/DC=DomainDnsZones,DC=domain,DC=net'], 'type': 'searchResRef'} {'uri': ['ldap://ForestDnsZones.domain.net/DC=ForestDnsZones,DC=domain,DC=net'], 'type': 'searchResRef'} {'uri': ['ldap://domain.net/CN=Configuration,DC=domain,DC=net'], 'type': 'searchResRef'} and doens't have any attributes. You can try to set the auto_referrals parameter to True in the connection object and specify a list of allowed_referrals_hosts in the Server object (you can set it to '*' to allow all server referred in the response). Let me know if this solve your problem. Bye, Giovanni Have fun, gc 2014-03-21 19:10 GMT+01:00 Andrew Hydle : > Hi, > > I am getting a key error when I start looping through c.response. Looking at > the data coming out of c.repsonse I am wondering if the dictionary that I am > receiving is missing a } > > I am running python 3.4.0 / python3-ldap 0.9.0 on Windows 7 > > [{'raw_attributes': {'displayName': [b'First Last'], 'description': [b'LDAP > Description']}, 'dn': 'CN=First > Last,OU=OU,OU=Users,OU=CITY,OU=company,DC=domain,DC=net', 'type': > 'searchResEntry', 'attributes': {'displayName': ['First Last'], > 'description': ['LDAP Description']}}, {'uri': > ['ldap://DomainDnsZones.domain.net/DC=DomainDnsZones,DC=domain,DC=net'],'type': > 'searchResRef'}, > {'uri':['ldap://ForestDnsZones.domain.net/DC=ForestDnsZones,DC=domain,DC=net'], > 'type': 'searchResRef'}, {'uri': > ['ldap://domain.net/CN=Configuration,DC=domain,DC=net'], 'type': > 'searchResRef'}] > > {'displayName': ['First Last'], 'description': ['LDAP Description']} > Traceback (most recent call last): > File "sapADImport.py", line 31, in > print(r['attributes']) > KeyError: 'attributes' > > ------------------------------------------- > > from ldap3 import Server, Connection > from ldap3 import AUTH_SIMPLE, STRATEGY_SYNC, STRATEGY_ASYNC_THREADED, > SEARCH_SCOPE_WHOLE_SUBTREE, SEARCH_DEREFERENCE_ALWAYS, GET_ALL_INFO > > s = Server(args.srvr, port=int(args.sprt), get_info=GET_ALL_INFO) > c = Connection(s, auto_bind=True, client_strategy=STRATEGY_SYNC, > user=args.user, password=args.pasw, authentication=AUTH_SIMPLE) > > lfilter = '(&(objectCategory=person)(sAMAccountName=%s))' % uid.lower() > result = c.search(search_base=args.bdn, search_filter=lfilter, > search_scope=SEARCH_SCOPE_WHOLE_SUBTREE, attributes=['displayName', > 'description']) > > > print(c.response) > if result: > for r in c.response: > print(r['attributes']) > > else: > print('result', c.result) > > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ahydle at gmail.com Fri Mar 21 23:12:24 2014 From: ahydle at gmail.com (Andrew Hydle) Date: Fri, 21 Mar 2014 15:12:24 -0700 Subject: [python3-ldap] Key error help In-Reply-To: <532cb79c.86440f0a.4693.fffff326@mx.google.com> References: <532cb79c.86440f0a.4693.fffff326@mx.google.com> Message-ID: It is querying against Windows Server 2012 Active Directory. If I perform the search on those URI's I dont believe it will return any of my users. Those are specific schema containers for active directory. Is there a way I can get it to not come back in the response? On Fri, Mar 21, 2014 at 3:05 PM, Python3-ldap wrote: > This means that the auto_referral is not working for that Uri. > Can you tell me the server version you're connecting to? I could try to > set up a lab server. In the meanwhile you should repeat the search in the > contest specified in the result Uri. > > Giovanni > > gc > ------------------------------ > Da: Andrew Hydle > Inviato: 21/03/2014 21.51 > A: python3ldap > Cc: python3-ldap at python.org > Oggetto: Re: [python3-ldap] Key error help > > Hi Giovanni, > > I changed that as suggested but unfortunately I still get the same key > error: > > s = Server(args.srvr, port=int(args.sprt), get_info=GET_ALL_INFO, > allowed_referral_hosts='*') > c = Connection(s, auto_bind=True, client_strategy=STRATEGY_SYNC, > user=args.user, password=args.pasw, authentication=AUTH_SIMPLE, > auto_referrals=True) > > Can you think of anything else I could try? > > Thanks > > Andrew > > > On Fri, Mar 21, 2014 at 12:04 PM, python3ldap wrote: > >> Hello Andrew, >> there is no } missing, the problem is that your LDAP server returns as >> second, third and fourth element of the response a Search Result >> Referral that is a reference to another server: >> >> {'uri': ['ldap:// >> DomainDnsZones.domain.net/DC=DomainDnsZones,DC=domain,DC=net'], >> 'type': 'searchResRef'} >> {'uri': ['ldap:// >> ForestDnsZones.domain.net/DC=ForestDnsZones,DC=domain,DC=net'], >> 'type': 'searchResRef'} >> {'uri': ['ldap://domain.net/CN=Configuration,DC=domain,DC=net'], >> 'type': 'searchResRef'} >> >> and doens't have any attributes. You can try to set the >> auto_referrals parameter to True in the connection object and specify >> a list of allowed_referrals_hosts in the Server object (you can set it >> to '*' to allow all server referred in the response). >> >> Let me know if this solve your problem. >> >> Bye, >> Giovanni >> Have fun, >> gc >> >> >> 2014-03-21 19:10 GMT+01:00 Andrew Hydle : >> > Hi, >> > >> > I am getting a key error when I start looping through c.response. >> Looking at >> > the data coming out of c.repsonse I am wondering if the dictionary that >> I am >> > receiving is missing a } >> > >> > I am running python 3.4.0 / python3-ldap 0.9.0 on Windows 7 >> > >> > [{'raw_attributes': {'displayName': [b'First Last'], 'description': >> [b'LDAP >> > Description']}, 'dn': 'CN=First >> > Last,OU=OU,OU=Users,OU=CITY,OU=company,DC=domain,DC=net', 'type': >> > 'searchResEntry', 'attributes': {'displayName': ['First Last'], >> > 'description': ['LDAP Description']}}, {'uri': >> > ['ldap://DomainDnsZones.domain.net/DC=DomainDnsZones,DC=domain,DC=net' >> ],'type': >> > 'searchResRef'}, >> > {'uri':['ldap:// >> ForestDnsZones.domain.net/DC=ForestDnsZones,DC=domain,DC=net'], >> > 'type': 'searchResRef'}, {'uri': >> > ['ldap://domain.net/CN=Configuration,DC=domain,DC=net'], 'type': >> > 'searchResRef'}] >> > >> > {'displayName': ['First Last'], 'description': ['LDAP Description']} >> > Traceback (most recent call last): >> > File "sapADImport.py", line 31, in >> > print(r['attributes']) >> > KeyError: 'attributes' >> > >> > ------------------------------------------- >> > >> > from ldap3 import Server, Connection >> > from ldap3 import AUTH_SIMPLE, STRATEGY_SYNC, STRATEGY_ASYNC_THREADED, >> > SEARCH_SCOPE_WHOLE_SUBTREE, SEARCH_DEREFERENCE_ALWAYS, GET_ALL_INFO >> > >> > s = Server(args.srvr, port=int(args.sprt), get_info=GET_ALL_INFO) >> > c = Connection(s, auto_bind=True, client_strategy=STRATEGY_SYNC, >> > user=args.user, password=args.pasw, authentication=AUTH_SIMPLE) >> > >> > lfilter = '(&(objectCategory=person)(sAMAccountName=%s))' % uid.lower() >> > result = c.search(search_base=args.bdn, search_filter=lfilter, >> > search_scope=SEARCH_SCOPE_WHOLE_SUBTREE, attributes=['displayName', >> > 'description']) >> > >> > >> > print(c.response) >> > if result: >> > for r in c.response: >> > print(r['attributes']) >> > >> > else: >> > print('result', c.result) >> > >> > _______________________________________________ >> > python3-ldap mailing list >> > python3-ldap at python.org >> > https://mail.python.org/mailman/listinfo/python3-ldap >> > >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jcasale at activenetwerx.com Fri Mar 21 23:54:52 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Fri, 21 Mar 2014 22:54:52 +0000 Subject: [python3-ldap] Key error help In-Reply-To: References: <532cb79c.86440f0a.4693.fffff326@mx.google.com> Message-ID: <8e9893cb1ecd46898f498abc33e79e9c@exch.activenetwerx.com> > It is querying against Windows Server 2012 Active Directory. If I perform the search > on those URI's I dont believe it will return any of my users. Those are specific schema > containers for active directory. Is there a way I can get it to not come back in the response? (misdirected the first response...) Be more robust in your parsing, you are looking for an account object, this has a 'dn' or a 'type' of 'searchResEntry' for example... for resp in connection.response: if resp['type'] == 'searchResEntry': return resp['dn'], resp['attributes'] Additionally, don't index an object you don't know exists. Check for it first for example... hth, jlc From ahydle at gmail.com Sat Mar 22 01:54:00 2014 From: ahydle at gmail.com (Andrew Hydle) Date: Fri, 21 Mar 2014 17:54:00 -0700 Subject: [python3-ldap] Key error help In-Reply-To: <8e9893cb1ecd46898f498abc33e79e9c@exch.activenetwerx.com> References: <532cb79c.86440f0a.4693.fffff326@mx.google.com> <8e9893cb1ecd46898f498abc33e79e9c@exch.activenetwerx.com> Message-ID: A hah! That makes perfect sense. Thank you! On Fri, Mar 21, 2014 at 3:54 PM, Joseph L. Casale wrote: > > It is querying against Windows Server 2012 Active Directory. If I > perform the search > > on those URI's I dont believe it will return any of my users. Those are > specific schema > > containers for active directory. Is there a way I can get it to not come > back in the response? > > (misdirected the first response...) > > Be more robust in your parsing, you are looking for an account object, > this has a 'dn' or a > 'type' of 'searchResEntry' for example... > > for resp in connection.response: > if resp['type'] == 'searchResEntry': > return resp['dn'], resp['attributes'] > > Additionally, don't index an object you don't know exists. Check for it > first for example... > > hth, > jlc > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap > -------------- next part -------------- An HTML attachment was scrubbed... URL: From python3ldap at gmail.com Sat Mar 22 09:43:43 2014 From: python3ldap at gmail.com (python3ldap) Date: Sat, 22 Mar 2014 09:43:43 +0100 Subject: [python3-ldap] Key error help In-Reply-To: References: <532cb79c.86440f0a.4693.fffff326@mx.google.com> <8e9893cb1ecd46898f498abc33e79e9c@exch.activenetwerx.com> Message-ID: Hello Andrew, I think that Joseph's is the right solution. In LDAP there are two ways a server can use referral, "global referral" or "continuation referral". A global referral is a single response to an operation and means that the contacted server "cannot or will not perform the operation and that one or more other servers may be able to" (RFC4511, part 4.1.10) while a continuation referral can be mixed to the search entry results and means that the server "knows" that you could find additional entries in the referred server. Both of these referral kinds return the same "uri" attribute that is a list of servers (with dn of the base) to contact. python3-ldap can automatically follow the "global referral", issuing the same operation on one uf the server specified in the uri, in a recursive way, up to 10 levels (as specified in the RFC) and avoiding looping between servers, but not the continuation referrals. I should try to extend the referral "machinery" to the "continuation" types, but unitl now I didn't get a server where to test them. I put this feature in the "work to do" queue in the roadmap of the project. Bye, Giovanni Have fun, gc 2014-03-22 1:54 GMT+01:00 Andrew Hydle : > A hah! That makes perfect sense. Thank you! > > > On Fri, Mar 21, 2014 at 3:54 PM, Joseph L. Casale > wrote: >> >> > It is querying against Windows Server 2012 Active Directory. If I >> > perform the search >> > on those URI's I dont believe it will return any of my users. Those are >> > specific schema >> > containers for active directory. Is there a way I can get it to not come >> > back in the response? >> >> (misdirected the first response...) >> >> Be more robust in your parsing, you are looking for an account object, >> this has a 'dn' or a >> 'type' of 'searchResEntry' for example... >> >> for resp in connection.response: >> if resp['type'] == 'searchResEntry': >> return resp['dn'], resp['attributes'] >> >> Additionally, don't index an object you don't know exists. Check for it >> first for example... >> >> hth, >> jlc >> _______________________________________________ >> python3-ldap mailing list >> python3-ldap at python.org >> https://mail.python.org/mailman/listinfo/python3-ldap > > > > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap > From python3ldap at gmail.com Sun Mar 30 23:23:40 2014 From: python3ldap at gmail.com (python3ldap) Date: Sun, 30 Mar 2014 23:23:40 +0200 Subject: [python3-ldap] python3-ldap 0.9.1 released! Message-ID: Hello, I've released the 0.9.1 version of python3-ldap. This is mainly a bug fixing and tweaking version, with a new interesting feature: "lazy" connections. Now you can set lazy=True when creating a new connection, this means that the open() and bind() will be deferred until an effective ldap operation will be executed. This should work with synchronous, asynchronous and restartable connection. I changed the signature of the ServerPool, now it's possibile to specify if servers in the pool must be checked for availability and if the pool will be exhausted when no servers are available. I've extended tests to Python 3.4.0. (3.3, 2.7, 2.6 already tested). This is the changelog for version 0.9.1: * 0.9.1 2014.03.30 - added laziness to test suite - changed ServerPool signature to accept active and exhaust parameters - removed unneeded start_listen parameter - added 'lazy' parameter to open, bind and unbind a connection only when an effective operation is done - fixed start_tls in SyncWaitRestartable strategy - fixed certificate name checking while opening an ssl connection - fixed syntax error during installation - socket operations now raise proper exception, not generic LDAPException (thanks to Joseph) - tested against Python 3.4, 3.3, 2.7, 2.6 - updated setuptools to 3.3 Have fun, gc From richard-lists at esplins.org Wed Apr 16 00:33:51 2014 From: richard-lists at esplins.org (Richard Esplin) Date: Tue, 15 Apr 2014 16:33:51 -0600 Subject: [python3-ldap] Feature requests: clearer errors In-Reply-To: References: Message-ID: <1770412.hVuFfl9hGT@richs.localnet.esplins.org> Thank you for the great library. It is much more pythonic and easier to use than the old python-ldap. My only challenge in using the library is that there appears to only be one exception: LDAPException, and many error messages are very cryptic. It would help to have distinct exceptions for common errors. A good starting point would be to look at the exceptions listed in the documentation for the python- ldap module. Specific things clients need to identify: * auto_bind failure due to a bad basedn in the username parameter (python-ldap would return NO_SUCH_OBJECT), or due to a bad password (python-ldap would return INVALID_CREDENTIALS). Current message in the exception for both scenarios is: Exception: auto_bind not successful. This error made me first look at network connectivity. * using an ldaps URL and connecting on the standard port without using the SSL flag given an error about the socket closing unexpectedly. * using a CA cert in the local_certificate_file instead of the ca_certs_file gives an error about "[SSL] PEM lib (_ssl.c:2138)" that is completely unhelpful. Hopefully this is a useful suggestion to you, and my documenting what I found helps others. I plan on continuing to use this library. Thank you very much. Richard P.S. Please excuse the cross post. I originally posted this as an issue at Assemblia, but I couldn't figure out how to make it a public issue. Perhaps the re-post here might help other people diagnose these errors. I also hope the list activity helps anyone researching the library to see that it is reliable. From python3ldap at gmail.com Wed Apr 16 10:40:25 2014 From: python3ldap at gmail.com (python3ldap) Date: Wed, 16 Apr 2014 10:40:25 +0200 Subject: [python3-ldap] Feature requests: clearer errors In-Reply-To: <1770412.hVuFfl9hGT@richs.localnet.esplins.org> References: <1770412.hVuFfl9hGT@richs.localnet.esplins.org> Message-ID: Hello Richard, Thanks for your message, I know that the Exceptions management of python3-ldap is barely sufficient to know that an error has happened. I'm still working on some features I want to be in the 1.0 release of the library. Regarding this problem I think I will create a shallow hierarchy of exceptions. My problem is that I'm not sure if is better to let the socket errors (and other standard exceptions) flow up or trap them and re-raise a custom exception in a custom hierarchy. Do you have any suggestion? What other people in this list think about this? Bye, Giovanni 2014-04-16 0:33 GMT+02:00 Richard Esplin : > Thank you for the great library. It is much more pythonic and easier to use > than the old python-ldap. > > My only challenge in using the library is that there appears to only be one > exception: LDAPException, and many error messages are very cryptic. It would > help to have distinct exceptions for common errors. A good starting point > would be to look at the exceptions listed in the documentation for the python- > ldap module. > > Specific things clients need to identify: > * auto_bind failure due to a bad basedn in the username parameter (python-ldap > would return NO_SUCH_OBJECT), or due to a bad password (python-ldap would > return INVALID_CREDENTIALS). Current message in the exception for both > scenarios is: Exception: auto_bind not successful. This error made me first > look at network connectivity. > * using an ldaps URL and connecting on the standard port without using the SSL > flag given an error about the socket closing unexpectedly. > * using a CA cert in the local_certificate_file instead of the ca_certs_file > gives an error about "[SSL] PEM lib (_ssl.c:2138)" that is completely > unhelpful. > > Hopefully this is a useful suggestion to you, and my documenting what I found > helps others. > > I plan on continuing to use this library. Thank you very much. > > Richard > > P.S. Please excuse the cross post. I originally posted this as an issue at > Assemblia, but I couldn't figure out how to make it a public issue. Perhaps the > re-post here might help other people diagnose these errors. I also hope the > list activity helps anyone researching the library to see that it is reliable. > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap From michael at stroeder.com Wed Apr 16 11:29:32 2014 From: michael at stroeder.com (Michael =?UTF-8?B?U3Ryw7ZkZXI=?=) Date: Wed, 16 Apr 2014 11:29:32 +0200 Subject: [python3-ldap] Feature requests: clearer errors In-Reply-To: References: <1770412.hVuFfl9hGT@richs.localnet.esplins.org>, Message-ID: <6645a625a1177ec392cbddfab7125c1e@srv1.stroeder.com> On Wed, 16 Apr 2014 10:40:25 +0200 python3ldap wrote > My problem is that I'm not sure if is better to let the > socket errors (and other standard exceptions) flow up or trap them and > re-raise a custom exception in a custom hierarchy. Do you have any > suggestion? What other people in this list think about this? At least you should map any LDAP result code to a separate exception attaching more data returned by the server with the result like response controls. Otherwise fine-grained error handling is impossible. For socket errors I'd recommend to not catch them within your module. Just let the calling application deal with them. Ciao, Michael. From cito at online.de Wed Apr 16 11:43:54 2014 From: cito at online.de (Christoph Zwerschke) Date: Wed, 16 Apr 2014 11:43:54 +0200 Subject: [python3-ldap] Feature requests: clearer errors In-Reply-To: References: <1770412.hVuFfl9hGT@richs.localnet.esplins.org> Message-ID: <534E50DA.8050208@online.de> Am 16.04.2014 10:40, schrieb python3ldap: > Regarding this problem I think I will create a shallow hierarchy of > exceptions. My problem is that I'm not sure if is better to let the > socket errors (and other standard exceptions) flow up or trap them and > re-raise a custom exception in a custom hierarchy. Do you have any > suggestion? What other people in this list think about this? I think re-raising as a subclass of LDAPException is better, because you can catch every problem with a single exception handler. This is also how Requests and urllib do it. It's also important that all possible exceptions are properly documented. -- Christoph From python3ldap at gmail.com Wed Apr 16 21:09:47 2014 From: python3ldap at gmail.com (python3ldap) Date: Wed, 16 Apr 2014 21:09:47 +0200 Subject: [python3-ldap] Feature requests: clearer errors In-Reply-To: <6645a625a1177ec392cbddfab7125c1e@srv1.stroeder.com> References: <1770412.hVuFfl9hGT@richs.localnet.esplins.org> <6645a625a1177ec392cbddfab7125c1e@srv1.stroeder.com> Message-ID: Hello Michael, thanks for your response, in python3-ldap when you send an operation you get a boolean as return value that indicates if the operation is successful or not. You then can get the result details in connection.result. Do you mean that everytime that an operation is not successful I should raise an exception? I like the idea to let the socket exception flow up to the calling application, except than for the Restartable strategy, that autoreconnect to the server pool. Another solution could be to have an exception with mutiple inheritance, to let the calling application decide if to catch all LDAPExceptions in a single except clause or more fine-grained exceptions and use LDAPException as a catchall. I haven't seen many project with multiple inheritance for exceptions, so I'm quite cautious with this solution, maybe there are some drawbacks that I don't understand. Bye, Giovanni 2014-04-16 11:29 GMT+02:00 Michael Str?der : > On Wed, 16 Apr 2014 10:40:25 +0200 python3ldap wrote >> My problem is that I'm not sure if is better to let the >> socket errors (and other standard exceptions) flow up or trap them and >> re-raise a custom exception in a custom hierarchy. Do you have any >> suggestion? What other people in this list think about this? > > At least you should map any LDAP result code to a separate exception attaching > more data returned by the server with the result like response controls. > Otherwise fine-grained error handling is impossible. > > For socket errors I'd recommend to not catch them within your module. > Just let the calling application deal with them. > > Ciao, Michael. > > From python3ldap at gmail.com Wed Apr 16 21:35:50 2014 From: python3ldap at gmail.com (python3ldap) Date: Wed, 16 Apr 2014 21:35:50 +0200 Subject: [python3-ldap] Feature requests: clearer errors In-Reply-To: <534E50DA.8050208@online.de> References: <1770412.hVuFfl9hGT@richs.localnet.esplins.org> <534E50DA.8050208@online.de> Message-ID: Hello Christoph, youre point is quite different from Michael's one. This is how the library is working now. I should include more specific information aboute the error in the exception description. What do you think of the idea of multi inheritance exceptions? For example an exception caused by a socket error in the library could be defined as: import socket class LDAPException(Exception): pass class LDAPSocketError(LDAPException, socket.error): pass so you can catch it in your code with: try: some_ldap_operation() except LDAPSocketError: # manage socket errors except LDAPException: # manage all other LDAPExceptions or: try: some_ldap_operation() except LDAPException: # manage all LDAPExceptions (including socket error) or even: try: some_ldap_operation() except socket.error: # manage socket errors even in not generated by the ldap operation except LDAPException: # manage all other LDAPExceptions What do you think about this? Have fun, gc 2014-04-16 11:43 GMT+02:00 Christoph Zwerschke : > Am 16.04.2014 10:40, schrieb python3ldap: >> >> Regarding this problem I think I will create a shallow hierarchy of >> exceptions. My problem is that I'm not sure if is better to let the >> socket errors (and other standard exceptions) flow up or trap them and >> re-raise a custom exception in a custom hierarchy. Do you have any >> suggestion? What other people in this list think about this? > > > I think re-raising as a subclass of LDAPException is better, because you can > catch every problem with a single exception handler. This is also how > Requests and urllib do it. It's also important that all possible exceptions > are properly documented. > > -- Christoph > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap From jcasale at activenetwerx.com Wed Apr 16 21:46:47 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Wed, 16 Apr 2014 19:46:47 +0000 Subject: [python3-ldap] Feature requests: clearer errors In-Reply-To: <534E50DA.8050208@online.de> References: <1770412.hVuFfl9hGT@richs.localnet.esplins.org> <534E50DA.8050208@online.de> Message-ID: > I think re-raising as a subclass of LDAPException is better, because you can > catch every problem with a single exception handler. This is also how Requests > and urllib do it. It's also important that all possible exceptions are properly documented. Just my opinion but I disagree with that. You can't know my use case and if you trap an exception my scenario requires that yours doesn't, what am I to do? If you don't want or care about the type, broaden your own try/catch, but don't impact the usability of the library by such an approach. jlc From jcasale at activenetwerx.com Wed Apr 16 21:51:33 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Wed, 16 Apr 2014 19:51:33 +0000 Subject: [python3-ldap] Socket errors carried through Message-ID: I am using a server pool defined as : pool_strategy=POOLING_STRATEGY_ROUND_ROBIN active=True exhaust=True and yet I am intermittently seeing a WinError 10054, 'An existing connection was forcibly closed by the remote host' being passed up after I open a connection and initiate a few searches from it. These connections are very short lived, less than a minute usually so it's safe to say this is not a wait time / topology related issue. What are your thoughts Giovanni? Thanks, jlc -------------- next part -------------- An HTML attachment was scrubbed... URL: From python3ldap at gmail.com Wed Apr 16 22:17:53 2014 From: python3ldap at gmail.com (python3ldap) Date: Wed, 16 Apr 2014 22:17:53 +0200 Subject: [python3-ldap] Socket errors carried through In-Reply-To: References: Message-ID: Hi Joseph, you get the error while sending or after you have got the response? According to MSDN the server closes the connection: WSAECONNRESET 10054 Connection reset by peer. An existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host uses a hard close (see setsockopt for more information on the SO_LINGER option on the remote socket). This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress. Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET. LDAP specifies that if the server wants to reset connection you should get an unsolicited notification. python3-ldap checks for this kind of message from server. You should get a 'session terminated by server' in the connection.last_error attribute after the exception is raised. Can you check if this is the case? Giovanni 2014-04-16 21:51 GMT+02:00 Joseph L. Casale : > I am using a server pool defined as : > > > > pool_strategy=POOLING_STRATEGY_ROUND_ROBIN > > active=True > > exhaust=True > > > > and yet I am intermittently seeing a WinError 10054, ?An existing connection > > was forcibly closed by the remote host? being passed up after I open a > connection > > and initiate a few searches from it. > > > > These connections are very short lived, less than a minute usually so it?s > safe to say > > this is not a wait time / topology related issue. > > > > What are your thoughts Giovanni? > > Thanks, > > jlc > > > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap > From jcasale at activenetwerx.com Wed Apr 16 22:26:00 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Wed, 16 Apr 2014 20:26:00 +0000 Subject: [python3-ldap] Socket errors carried through In-Reply-To: References: Message-ID: <14f4a3366edb4913939fafb3dc6dbf98@exch.activenetwerx.com> > You should get a 'session terminated by server' > in the connection.last_error attribute after the exception is raised. > > Can you check if this is the case? Hi Giovanni, I will add this and get back to you. Thanks! jlc From cito at online.de Wed Apr 16 22:40:20 2014 From: cito at online.de (Christoph Zwerschke) Date: Wed, 16 Apr 2014 22:40:20 +0200 Subject: [python3-ldap] Feature requests: clearer errors In-Reply-To: References: <1770412.hVuFfl9hGT@richs.localnet.esplins.org> <534E50DA.8050208@online.de> Message-ID: <534EEAB4.7050004@online.de> Am 16.04.2014 21:46, schrieb Joseph L. Casale: >> I think re-raising as a subclass of LDAPException is better, >> because you cancatch every problem with a single exception handler. >> This is also how Requests and urllib do it. It's also important >> that all possible exceptions are properly documented. > > Just my opinion but I disagree with that. You can't know my use case > and if you trap an exception my scenario requires that yours > doesn't, what am I to do? Actually I don't see a problem here if the LDAPException subclasses re-raised by python3-ldap are fine-grained enough. Remember that exceptions are part of the API. The fact that python3-ldap uses the stdlib socket module is IMHO an implementation detail and python3-ldap should encapsulate that. -- Christoph From jcasale at activenetwerx.com Wed Apr 16 23:00:35 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Wed, 16 Apr 2014 21:00:35 +0000 Subject: [python3-ldap] Socket errors carried through In-Reply-To: References: Message-ID: <734ad66d2579420ca15adb365b438b5e@exch.activenetwerx.com> > You should get a 'session terminated by server' > in the connection.last_error attribute after the exception is raised. > > Can you check if this is the case? Well, that attr has the string value of: "socket closing error[WinError 10054] An existing connection was forcibly closed by the remote host." Not so sure we are that much further ahead:) jlc From michael at stroeder.com Wed Apr 16 23:27:54 2014 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Wed, 16 Apr 2014 23:27:54 +0200 Subject: [python3-ldap] Feature requests: clearer errors In-Reply-To: <534EEAB4.7050004@online.de> References: <1770412.hVuFfl9hGT@richs.localnet.esplins.org> <534E50DA.8050208@online.de> <534EEAB4.7050004@online.de> Message-ID: <534EF5DA.7090601@stroeder.com> Christoph Zwerschke wrote: > Am 16.04.2014 21:46, schrieb Joseph L. Casale: >>> I think re-raising as a subclass of LDAPException is better, >>> because you cancatch every problem with a single exception handler. >>> This is also how Requests and urllib do it. It's also important >>> that all possible exceptions are properly documented. >> >> Just my opinion but I disagree with that. You can't know my use case >> and if you trap an exception my scenario requires that yours >> doesn't, what am I to do? > > Actually I don't see a problem here if the LDAPException subclasses re-raised > by python3-ldap are fine-grained enough. Remember that exceptions are part of > the API. The fact that python3-ldap uses the stdlib socket module is IMHO an > implementation detail and python3-ldap should encapsulate that. If you think this to the end the API has to double all possible exceptions to be "fine-grained enough" and keep up with all the exceptions invented in the future. 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 Apr 16 23:34:52 2014 From: michael at stroeder.com (=?UTF-8?B?TWljaGFlbCBTdHLDtmRlcg==?=) Date: Wed, 16 Apr 2014 23:34:52 +0200 Subject: [python3-ldap] Feature requests: clearer errors In-Reply-To: References: <1770412.hVuFfl9hGT@richs.localnet.esplins.org> <6645a625a1177ec392cbddfab7125c1e@srv1.stroeder.com> Message-ID: <534EF77C.7090607@stroeder.com> python3ldap wrote: > in python3-ldap when you send an operation you get a boolean as return > value that indicates if the operation is successful or not. You then > can get the result details in connection.result. Frankly I did not look at your code yet. But that does not sound like the approach I would want to deal with. > Do you mean that everytime that an operation is not successful I should > raise an exception? Yes, that's what I need e.g. within web2ldap where the exception handler might be located several calling layers above. Especially I really like that you can let exceptions flow without having to deal with them on all layers (like IIRC Java requires). But don't forget to attach all available result data to the exception object which might be needed by the caller (e.g. response controls). That's one of the deficiencies of current python-ldap. > I like the idea to let the socket exception flow up to the calling > application, except than for the Restartable strategy, that > autoreconnect to the server pool. Catch the exception, retry with counter and re-raise if all fails. 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 Apr 17 00:50:25 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Wed, 16 Apr 2014 22:50:25 +0000 Subject: [python3-ldap] Socket errors carried through In-Reply-To: <534efce4.830a0f0a.541a.7172@mx.google.com> References: <534efce4.830a0f0a.541a.7172@mx.google.com> Message-ID: <1d612f099b174260b6be6330d2ee6285@exch.activenetwerx.com> > This means that the server is not sending an unsolicited Message. > When you get this exception? While sending or receiving? On the outbound search request, I couldn't tell you without patching the library and adding log statements. I did notice something rather wasteful though, I make several search attempts separated by a short bit of logic and each of those leverages a context manager with the connection and given the connection is not instantiated and opened/bound its cycling servers or each search. Not really efficient. I am going to open the connection before I pass it along, it should cycle through to the first available server at that time and maintain a known working connection for the next minute while I make a few searches. Thanks, jlc From richard at esplins.org Thu Apr 17 22:46:44 2014 From: richard at esplins.org (Richard Esplin) Date: Thu, 17 Apr 2014 14:46:44 -0600 Subject: [python3-ldap] Feature requests: clearer errors In-Reply-To: <534EF5DA.7090601@stroeder.com> References: <534EEAB4.7050004@online.de> <534EF5DA.7090601@stroeder.com> Message-ID: <1935508.8BJK0JoTtX@richs.localnet.esplins.org> Interesting discussion. urllib is the example you should follow. Every exception generated in your code should get trapped and re-raised as an exception that inherits from LDAPException. That way the client can identify that the exception originated in your code, and you can provide a message to clarify the circumstances of the exception. The current socket exception doesn't look any different from socket exceptions generated in other parts of my code. I have to carefully read the stack trace to understand which socket is giving me problems. An LDAPException would make that obvious. Even if I do identify that it is an LDAP socket, I have to go read the library source to get an idea for how that socket was being used in order to figure out how I should respond to the exception. The library author is in a position where he or she can provide a lot of guidance by trapping and re-raising the exception. It is understandable if a new exception, or unusually rare exception is not trapped and leaks through to the client. But that should not be the common case, and should be a sign that the error is unusual. Richard On Wednesday, April 16, 2014 23:27:54 Michael Str?der wrote: > Christoph Zwerschke wrote: > > Am 16.04.2014 21:46, schrieb Joseph L. Casale: > >>> I think re-raising as a subclass of LDAPException is better, > >>> because you cancatch every problem with a single exception handler. > >>> This is also how Requests and urllib do it. It's also important > >>> that all possible exceptions are properly documented. > >> > >> Just my opinion but I disagree with that. You can't know my use case > >> > >> and if you trap an exception my scenario requires that yours > >> > >> doesn't, what am I to do? > > > > Actually I don't see a problem here if the LDAPException subclasses > > re-raised by python3-ldap are fine-grained enough. Remember that > > exceptions are part of the API. The fact that python3-ldap uses the > > stdlib socket module is IMHO an implementation detail and python3-ldap > > should encapsulate that. > > If you think this to the end the API has to double all possible exceptions > to be "fine-grained enough" and keep up with all the exceptions invented in > the future. > > Ciao, Michael. From richard-lists at esplins.org Fri Apr 18 08:09:52 2014 From: richard-lists at esplins.org (Richard Esplin) Date: Fri, 18 Apr 2014 00:09:52 -0600 Subject: [python3-ldap] Feature requests: clearer errors In-Reply-To: <534EF5DA.7090601@stroeder.com> References: <534EEAB4.7050004@online.de> <534EF5DA.7090601@stroeder.com> Message-ID: <4984591.aR9XieYVYq@richs.localnet.esplins.org> Interesting discussion. urllib is the example you should follow. Every exception generated in your code should get trapped and re-raised as an exception that inherits from LDAPException. That way the client can identify that the exception originated in your code, and you can provide a message to clarify the circumstances of the exception. The current socket exception doesn't look any different from socket exceptions generated in other parts of my code. I have to carefully read the stack trace to understand which socket is giving me problems. An LDAPException would make that obvious. Even if I do identify that it is an LDAP socket, I have to go read the library source to get an idea for how that socket was being used in order to figure out how I should respond to the exception. The library author is in a position where he or she can provide a lot of guidance by trapping and re-raising the exception. It is understandable if a new exception, or unusually rare exception is not trapped and leaks through to the client. But that should not be the common case, and should be a sign that the error is unusual. Richard On Wednesday, April 16, 2014 23:27:54 Michael Str?der wrote: > Christoph Zwerschke wrote: > > Am 16.04.2014 21:46, schrieb Joseph L. Casale: > >>> I think re-raising as a subclass of LDAPException is better, > >>> because you cancatch every problem with a single exception handler. > >>> This is also how Requests and urllib do it. It's also important > >>> that all possible exceptions are properly documented. > >> > >> Just my opinion but I disagree with that. You can't know my use case > >> > >> and if you trap an exception my scenario requires that yours > >> > >> doesn't, what am I to do? > > > > Actually I don't see a problem here if the LDAPException subclasses > > re-raised by python3-ldap are fine-grained enough. Remember that > > exceptions are part of the API. The fact that python3-ldap uses the > > stdlib socket module is IMHO an implementation detail and python3-ldap > > should encapsulate that. > > If you think this to the end the API has to double all possible exceptions > to be "fine-grained enough" and keep up with all the exceptions invented in > the future. > > Ciao, Michael. From python3ldap at gmail.com Fri Apr 18 10:38:20 2014 From: python3ldap at gmail.com (python3ldap) Date: Fri, 18 Apr 2014 10:38:20 +0200 Subject: [python3-ldap] Feature requests: clearer errors In-Reply-To: <4984591.aR9XieYVYq@richs.localnet.esplins.org> References: <534EEAB4.7050004@online.de> <534EF5DA.7090601@stroeder.com> <4984591.aR9XieYVYq@richs.localnet.esplins.org> Message-ID: HI Richiards, I agree with your message. I think we can have a LDAPException hierarchy with two branches, one for LDAPOperationErrors and one for LDAPCommunicationErrors, the exception in LDAPCommunicationErrors could hinerit from the real exception too, so it can be catched either as an LDAPException and a OSError exception. Have fun, gc 2014-04-18 8:09 GMT+02:00 Richard Esplin : > Interesting discussion. > > urllib is the example you should follow. > > Every exception generated in your code should get trapped and re-raised as an > exception that inherits from LDAPException. That way the client can identify > that the exception originated in your code, and you can provide a message to > clarify the circumstances of the exception. > > The current socket exception doesn't look any different from socket exceptions > generated in other parts of my code. I have to carefully read the stack trace > to understand which socket is giving me problems. An LDAPException would make > that obvious. > > Even if I do identify that it is an LDAP socket, I have to go read the library > source to get an idea for how that socket was being used in order to figure out > how I should respond to the exception. The library author is in a position > where he or she can provide a lot of guidance by trapping and re-raising the > exception. > > It is understandable if a new exception, or unusually rare exception is not > trapped and leaks through to the client. But that should not be the common > case, and should be a sign that the error is unusual. > > Richard > > On Wednesday, April 16, 2014 23:27:54 Michael Str?der wrote: >> Christoph Zwerschke wrote: >> > Am 16.04.2014 21:46, schrieb Joseph L. Casale: >> >>> I think re-raising as a subclass of LDAPException is better, >> >>> because you cancatch every problem with a single exception handler. >> >>> This is also how Requests and urllib do it. It's also important >> >>> that all possible exceptions are properly documented. >> >> >> >> Just my opinion but I disagree with that. You can't know my use case >> >> >> >> and if you trap an exception my scenario requires that yours >> >> >> >> doesn't, what am I to do? >> > >> > Actually I don't see a problem here if the LDAPException subclasses >> > re-raised by python3-ldap are fine-grained enough. Remember that >> > exceptions are part of the API. The fact that python3-ldap uses the >> > stdlib socket module is IMHO an implementation detail and python3-ldap >> > should encapsulate that. >> >> If you think this to the end the API has to double all possible exceptions >> to be "fine-grained enough" and keep up with all the exceptions invented in >> the future. >> >> Ciao, Michael. > > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap From python3ldap at gmail.com Sat Apr 26 22:59:26 2014 From: python3ldap at gmail.com (python3ldap) Date: Sat, 26 Apr 2014 22:59:26 +0200 Subject: [python3-ldap] Python3-ldap 0.9.2 is released Message-ID: Hello everybody, version 0.9.2 of python3-ldap is out. There is a new feature in this release and a number of fixes and improvements. - The new feature is the ReusableThreaded strategy. This asynchronous strategy let you to create a pool of connection to one or more ldap servers and access them through a multi-threaded connection pool. It's similar to ldappool but it should be easier to use because you jsut define a single Connection with this strategy and it creates under the hood a pool of lazy Restartable connections, each with its own running thread that connects to the servers defined in the ServerPool of the connection object. You must pass a pool_name while creating this kind of connection. The pool_name defines a "singleton" pool of connections that can be accessed through the connection itself or via any other ReusableThreaded connection that use the same pool_name. You can pass a pool_size (default is 10) and a pool_lifetime (default is 3600 (1 hour) that refresh each connection when the lifetime is expired, together with the pool_name. To close the connection pool you must use the connection.strategy.terminale() method. The ReusableThreaded strategy should be used in long standing application server but keep in mind that this is a first release of this strategy and the code is not really well tested in production. Please let me know.if you are interested or have suggestion on how to improve this strategy. - I've made the difference between the response and the result attributes more clear. Now in all strategies result contains the result message of the ldap operation requested while response contains any other message sent back by the server. Previously this was true only for the search operation, while now all operations have the same behaviour. - When using an async strategy the get_response(id) method now returns two values, the response and the result. This is needed to avoid problems when using threaded connections. - All operation now are more consistent with the RFC4515 regarding to binary data value. RFC4515 specify that binary data hex must be escaped with a backslash as in \01\02\03\0FF. You can now pass this format directly in the attribute values with adding, modifying or comparing operation and in the search filter for search operation. There is a convenience function to convert a bytes object to this escape format: escape_bytes(bytes_value) in the new ldap.utils.conv namespace. This is the full changelog for 0.9.2: - changed return value in get_response from response to (response, result) - helpful for multi threaded connections - added ReusableStrategy for pooling connections - refined docstrings (thanks to Will) - result and response attributes don't overlap anymore. Operation result is only in result attribute. - fixed search for binary values (thanks to Marcin) - added convenience function to convert bytes to LDAP binary value string format for search filter Have fun. gc From mehaase at gmail.com Tue Apr 29 06:04:07 2014 From: mehaase at gmail.com (Mark E. Haase) Date: Tue, 29 Apr 2014 00:04:07 -0400 Subject: [python3-ldap] Trouble with STARTTLS Message-ID: I really like python3-ldap. Much cleaner than building on top of OpenLDAP :) I can get TLS working on port 636, but I can't figure out how to get Start TLS on port 389. Here's what I have so far (Python 2.7): 01 import ldap3 02 import os 03 import ssl 04 05 host = "ldap.*************.net" 06 port = 389 07 username = "cn=admin,dc=*************,dc=net" 08 password = "*************" 09 base_path = os.path.dirname(os.path.realpath(__file__)) 10 11 tls = ldap3.Tls(validate=ssl.CERT_REQUIRED, ca_certs_file=os.path.join(base_path, "goodca")) 12 ldap_server = ldap3.Server(host, port=port, use_ssl=False, tls=tls) 13 ldap_handle = ldap3.Connection(ldap_server, user=username, password=password) 14 ldap_handle.open() 15 ldap_handle.start_tls() 16 ldap_handle.bind() I'm ~100% sure that "goodca" is not the problem, because I've validated it with openssl s_client, gnutls-cli, ldapsearch, and python-ldap. It's PEM encoded. When I run this example, I get this exception: mhaase at luci:~/luci/bin$ python test.py Traceback (most recent call last): File "test.py", line 15, in ldap_handle.start_tls() File "/usr/local/lib/python2.7/dist-packages/ldap3/core/connection.py", line 535, in start_tls if self.server.tls.start_tls(self): File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line 118, in start_tls return self._start_tls(connection) File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line 121, in _start_tls connection.socket = self.wrap_socket(connection, False) File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line 91, in wrap_socket check_hostname(wrapped_socket, connection.server.host, self.valid_names) File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line 206, in check_hostname match_hostname_backport(server_certificate, host_name) File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line 168, in match_hostname_backport raise ValueError("empty or no certificate") ValueError: empty or no certificate Any ideas what I'm doing wrong? Any help would be greatly appreciated... I've been struggling with openldap/python-ldap/python3-for 12 hours today!! -------------- next part -------------- An HTML attachment was scrubbed... URL: From python3ldap at gmail.com Tue Apr 29 08:23:26 2014 From: python3ldap at gmail.com (python3ldap) Date: Tue, 29 Apr 2014 08:23:26 +0200 Subject: [python3-ldap] Trouble with STARTTLS In-Reply-To: References: Message-ID: Hello Mark, could you try the same operation with python 3? Python 2 is (with no apparent reason) missing a fundamental check in ssl handshake (match hostname in certificate with a valid list of names), so I backported it from 3 to 2 (the match_hostname_backport function). If your code works with python 3 maybe there is a problem in the backport function. Or you can try to disable the whole match_hostname passing a valid_names='*' parameter in the Tls() creation. Bye, gc Il marted? 29 aprile 2014, Mark E. Haase ha scritto: > I really like python3-ldap. Much cleaner than building on top of OpenLDAP > :) > > I can get TLS working on port 636, but I can't figure out how to get Start > TLS on port 389. Here's what I have so far (Python 2.7): > > 01 import ldap3 > 02 import os > 03 import ssl > 04 > 05 host = "ldap.*************.net" > 06 port = 389 > 07 username = "cn=admin,dc=*************,dc=net" > 08 password = "*************" > 09 base_path = os.path.dirname(os.path.realpath(__file__)) > 10 > 11 tls = ldap3.Tls(validate=ssl.CERT_REQUIRED, > ca_certs_file=os.path.join(base_path, "goodca")) > 12 ldap_server = ldap3.Server(host, port=port, use_ssl=False, tls=tls) > 13 ldap_handle = ldap3.Connection(ldap_server, user=username, > password=password) > 14 ldap_handle.open() > 15 ldap_handle.start_tls() > 16 ldap_handle.bind() > > I'm ~100% sure that "goodca" is not the problem, because I've validated it > with openssl s_client, gnutls-cli, ldapsearch, and python-ldap. It's PEM > encoded. When I run this example, I get this exception: > > mhaase at luci:~/luci/bin$ python test.py > Traceback (most recent call last): > File "test.py", line 15, in > ldap_handle.start_tls() > File "/usr/local/lib/python2.7/dist-packages/ldap3/core/connection.py", > line 535, in start_tls > if self.server.tls.start_tls(self): > File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line > 118, in start_tls > return self._start_tls(connection) > File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line > 121, in _start_tls > connection.socket = self.wrap_socket(connection, False) > File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line > 91, in wrap_socket > check_hostname(wrapped_socket, connection.server.host, > self.valid_names) > File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line > 206, in check_hostname > match_hostname_backport(server_certificate, host_name) > File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line > 168, in match_hostname_backport > raise ValueError("empty or no certificate") > ValueError: empty or no certificate > > Any ideas what I'm doing wrong? Any help would be greatly appreciated... > I've been struggling with openldap/python-ldap/python3-for 12 hours today!! > -- Have fun, gc -------------- next part -------------- An HTML attachment was scrubbed... URL: From mehaase at gmail.com Tue Apr 29 20:47:27 2014 From: mehaase at gmail.com (Mark E. Haase) Date: Tue, 29 Apr 2014 14:47:27 -0400 Subject: [python3-ldap] Trouble with STARTTLS In-Reply-To: References: Message-ID: Thanks for the reply, gc. I tried with Python 3 with different but still unsuccessful results: Here is one machine I tried on: $ python3 --version Python 3.2.3 $ python3 test.py Traceback (most recent call last): File "test.py", line 15, in ldap_handle.start_tls() File "/usr/local/lib/python3.2/dist-packages/ldap3/core/connection.py", line 535, in start_tls if self.server.tls.start_tls(self): File "/usr/local/lib/python3.2/dist-packages/ldap3/core/tls.py", line 118, in start_tls return self._start_tls(connection) File "/usr/local/lib/python3.2/dist-packages/ldap3/core/tls.py", line 121, in _start_tls connection.socket = self.wrap_socket(connection, False) File "/usr/local/lib/python3.2/dist-packages/ldap3/core/tls.py", line 91, in wrap_socket check_hostname(wrapped_socket, connection.server.host, self.valid_names) File "/usr/local/lib/python3.2/dist-packages/ldap3/core/tls.py", line 203, in check_hostname ssl.match_hostname(server_certificate, host_name) # raise CertificateError if certificate doesn't match server name File "/usr/lib/python3.2/ssl.py", line 141, in match_hostname raise ValueError("empty or no certificate") ValueError: empty or no certificate Here's another: $ python3 --version Python 3.4.0 $ python3 test.py Traceback (most recent call last): File "test.py", line 15, in ldap_handle.start_tls() File "/usr/local/lib/python3.4/dist-packages/ldap3/core/connection.py", line 535, in start_tls if self.server.tls.start_tls(self): File "/usr/local/lib/python3.4/dist-packages/ldap3/core/tls.py", line 118, in start_tls return self._start_tls(connection) File "/usr/local/lib/python3.4/dist-packages/ldap3/core/tls.py", line 121, in _start_tls connection.socket = self.wrap_socket(connection, False) File "/usr/local/lib/python3.4/dist-packages/ldap3/core/tls.py", line 91, in wrap_socket check_hostname(wrapped_socket, connection.server.host, self.valid_names) File "/usr/local/lib/python3.4/dist-packages/ldap3/core/tls.py", line 196, in check_hostname server_certificate = sock.getpeercert() File "/usr/lib/python3.4/ssl.py", line 648, in getpeercert return self._sslobj.peer_certificate(binary_form) ValueError: handshake not done yet This is apparently a new error in Python 3.4, according to the python docs. I took a closer look at core/tls.py, and I see in wrap_socket(), lines 90-91 perform a hostname check, but these lines are redundant with lines 128-129 in _start_tls(). Furthermore, these lines execute *before* the handshake at line 123. I tried making the following change and my test script doesn't throw any exceptions. I haven't tested it any deeper yet because I wanted to get your feedback. core/tls.py: 84 def wrap_socket(self, connection, do_handshake=False): 85 """ 86 Adds TLS to a plain socket and returns the SSL socket 87 """ 88 wrapped_socket = ssl.wrap_socket(connection.socket, keyfile=self.private_key_file, certfile=self.certificate_file, server _side=False, cert_reqs=self.validate, ssl_version=self.version, ca_certs=self.ca_certs_file, do_handshake_on_connect=do_handshake ) 89 90 if do_handshake and self.validate == ssl.CERT_REQUIRED or self.validate == ssl.CERT_OPTIONAL: 91 check_hostname(wrapped_socket, connection.server.host, self.valid_names) 92 93 return wrapped_socket At line 90 I added the "do_handshake and" condition. I believe this would fix the starttls operation without breaking any existing callers to wrap_socket. What do you think? On Tue, Apr 29, 2014 at 2:23 AM, python3ldap wrote: > > Hello Mark, could you try the same operation with python 3? Python 2 is > (with no apparent reason) missing a fundamental check in ssl handshake > (match hostname in certificate with a valid list of names), so I backported > it from 3 to 2 (the match_hostname_backport function). If your code works > with python 3 maybe there is a problem in the backport function. Or you can > try to disable the whole match_hostname passing a valid_names='*' parameter > in the Tls() creation. > > Bye, > gc > > > Il marted? 29 aprile 2014, Mark E. Haase ha scritto: > > I really like python3-ldap. Much cleaner than building on top of OpenLDAP >> :) >> >> I can get TLS working on port 636, but I can't figure out how to get >> Start TLS on port 389. Here's what I have so far (Python 2.7): >> >> 01 import ldap3 >> 02 import os >> 03 import ssl >> 04 >> 05 host = "ldap.*************.net" >> 06 port = 389 >> 07 username = "cn=admin,dc=*************,dc=net" >> 08 password = "*************" >> 09 base_path = os.path.dirname(os.path.realpath(__file__)) >> 10 >> 11 tls = ldap3.Tls(validate=ssl.CERT_REQUIRED, >> ca_certs_file=os.path.join(base_path, "goodca")) >> 12 ldap_server = ldap3.Server(host, port=port, use_ssl=False, tls=tls) >> 13 ldap_handle = ldap3.Connection(ldap_server, user=username, >> password=password) >> 14 ldap_handle.open() >> 15 ldap_handle.start_tls() >> 16 ldap_handle.bind() >> >> I'm ~100% sure that "goodca" is not the problem, because I've validated >> it with openssl s_client, gnutls-cli, ldapsearch, and python-ldap. It's PEM >> encoded. When I run this example, I get this exception: >> >> mhaase at luci:~/luci/bin$ python test.py >> Traceback (most recent call last): >> File "test.py", line 15, in >> ldap_handle.start_tls() >> File "/usr/local/lib/python2.7/dist-packages/ldap3/core/connection.py", >> line 535, in start_tls >> if self.server.tls.start_tls(self): >> File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line >> 118, in start_tls >> return self._start_tls(connection) >> File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line >> 121, in _start_tls >> connection.socket = self.wrap_socket(connection, False) >> File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line >> 91, in wrap_socket >> check_hostname(wrapped_socket, connection.server.host, >> self.valid_names) >> File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line >> 206, in check_hostname >> match_hostname_backport(server_certificate, host_name) >> File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line >> 168, in match_hostname_backport >> raise ValueError("empty or no certificate") >> ValueError: empty or no certificate >> >> Any ideas what I'm doing wrong? Any help would be greatly appreciated... >> I've been struggling with openldap/python-ldap/python3-for 12 hours today!! >> > > > -- > Have fun, > gc > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From python3ldap at gmail.com Tue Apr 29 22:24:32 2014 From: python3ldap at gmail.com (python3ldap) Date: Tue, 29 Apr 2014 22:24:32 +0200 Subject: [python3-ldap] Trouble with STARTTLS In-Reply-To: References: Message-ID: Hi Mark, thanks for your great job in debugging this issue. I refactored the start_tls code in version 0.9.1 and must have messed up the code base. There should be no redundant checking for site names and name checking cannot obviuosly performed before handshake. I will fix this bug as soon as I can. In the meanwhile I apologize for wasting your time while trying to understand what was wrong. Bye, gc Il marted? 29 aprile 2014, Mark E. Haase ha scritto: > Thanks for the reply, gc. I tried with Python 3 with different but still > unsuccessful results: > > Here is one machine I tried on: > > $ python3 --version > Python 3.2.3 > $ python3 test.py > Traceback (most recent call last): > File "test.py", line 15, in > ldap_handle.start_tls() > File "/usr/local/lib/python3.2/dist-packages/ldap3/core/connection.py", > line 535, in start_tls > if self.server.tls.start_tls(self): > File "/usr/local/lib/python3.2/dist-packages/ldap3/core/tls.py", line > 118, in start_tls > return self._start_tls(connection) > File "/usr/local/lib/python3.2/dist-packages/ldap3/core/tls.py", line > 121, in _start_tls > connection.socket = self.wrap_socket(connection, False) > File "/usr/local/lib/python3.2/dist-packages/ldap3/core/tls.py", line > 91, in wrap_socket > check_hostname(wrapped_socket, connection.server.host, > self.valid_names) > File "/usr/local/lib/python3.2/dist-packages/ldap3/core/tls.py", line > 203, in check_hostname > ssl.match_hostname(server_certificate, host_name) # raise > CertificateError if certificate doesn't match server name > File "/usr/lib/python3.2/ssl.py", line 141, in match_hostname > raise ValueError("empty or no certificate") > ValueError: empty or no certificate > > Here's another: > > $ python3 --version > Python 3.4.0 > $ python3 test.py > Traceback (most recent call last): > File "test.py", line 15, in > ldap_handle.start_tls() > File "/usr/local/lib/python3.4/dist-packages/ldap3/core/connection.py", > line 535, in start_tls > if self.server.tls.start_tls(self): > File "/usr/local/lib/python3.4/dist-packages/ldap3/core/tls.py", line > 118, in start_tls > return self._start_tls(connection) > File "/usr/local/lib/python3.4/dist-packages/ldap3/core/tls.py", line > 121, in _start_tls > connection.socket = self.wrap_socket(connection, False) > File "/usr/local/lib/python3.4/dist-packages/ldap3/core/tls.py", line > 91, in wrap_socket > check_hostname(wrapped_socket, connection.server.host, > self.valid_names) > File "/usr/local/lib/python3.4/dist-packages/ldap3/core/tls.py", line > 196, in check_hostname > server_certificate = sock.getpeercert() > File "/usr/lib/python3.4/ssl.py", line 648, in getpeercert > return self._sslobj.peer_certificate(binary_form) > ValueError: handshake not done yet > > This is apparently a new error in Python 3.4, according to the python docs. > > I took a closer look at core/tls.py, and I see in wrap_socket(), lines > 90-91 perform a hostname check, but these lines are redundant with lines > 128-129 in _start_tls(). Furthermore, these lines execute *before* the > handshake at line 123. I tried making the following change and my test > script doesn't throw any exceptions. I haven't tested it any deeper yet > because I wanted to get your feedback. > > core/tls.py: > 84 def wrap_socket(self, connection, do_handshake=False): > 85 """ > 86 Adds TLS to a plain socket and returns the SSL socket > 87 """ > 88 wrapped_socket = ssl.wrap_socket(connection.socket, > keyfile=self.private_key_file, certfile=self.certificate_file, server > _side=False, cert_reqs=self.validate, ssl_version=self.version, > ca_certs=self.ca_certs_file, do_handshake_on_connect=do_handshake ) > 89 > 90 if do_handshake and self.validate == ssl.CERT_REQUIRED or > self.validate == ssl.CERT_OPTIONAL: > 91 check_hostname(wrapped_socket, connection.server.host, > self.valid_names) > 92 > 93 return wrapped_socket > > At line 90 I added the "do_handshake and" condition. I believe this would > fix the starttls operation without breaking any existing callers to > wrap_socket. > > What do you think? > > > > On Tue, Apr 29, 2014 at 2:23 AM, python3ldap > > wrote: > >> >> Hello Mark, could you try the same operation with python 3? Python 2 is >> (with no apparent reason) missing a fundamental check in ssl handshake >> (match hostname in certificate with a valid list of names), so I backported >> it from 3 to 2 (the match_hostname_backport function). If your code works >> with python 3 maybe there is a problem in the backport function. Or you can >> try to disable the whole match_hostname passing a valid_names='*' parameter >> in the Tls() creation. >> >> Bye, >> gc >> >> >> Il marted? 29 aprile 2014, Mark E. Haase > >> ha scritto: >> >> I really like python3-ldap. Much cleaner than building on top of OpenLDAP >>> :) >>> >>> I can get TLS working on port 636, but I can't figure out how to get >>> Start TLS on port 389. Here's what I have so far (Python 2.7): >>> >>> 01 import ldap3 >>> 02 import os >>> 03 import ssl >>> 04 >>> 05 host = "ldap.*************.net" >>> 06 port = 389 >>> 07 username = "cn=admin,dc=*************,dc=net" >>> 08 password = "*************" >>> 09 base_path = os.path.dirname(os.path.realpath(__file__)) >>> 10 >>> 11 tls = ldap3.Tls(validate=ssl.CERT_REQUIRED, >>> ca_certs_file=os.path.join(base_path, "goodca")) >>> 12 ldap_server = ldap3.Server(host, port=port, use_ssl=False, tls=tls) >>> 13 ldap_handle = ldap3.Connection(ldap_server, user=username, >>> password=password) >>> 14 ldap_handle.open() >>> 15 ldap_handle.start_tls() >>> 16 ldap_handle.bind() >>> >>> I'm ~100% sure that "goodca" is not the problem, because I've validated >>> it with openssl s_client, gnutls-cli, ldapsearch, and python-ldap. It's PEM >>> encoded. When I run this example, I get this exception: >>> >>> mhaase at luci:~/luci/bin$ python test.py >>> Traceback (most recent call last): >>> File "test.py", line 15, in >>> ldap_handle.start_tls() >>> File >>> "/usr/local/lib/python2.7/dist-packages/ldap3/core/connection.py", line >>> 535, in start_tls >>> if self.server.tls.start_tls(self): >>> File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line >>> 118, in start_tls >>> return self._start_tls(connection) >>> File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line >>> 121, in _start_tls >>> connection.socket = self.wrap_socket(connection, False) >>> File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line >>> 91, in wrap_socket >>> check_hostname(wrapped_socket, connection.server.host, >>> self.valid_names) >>> File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line >>> 206, in check_hostname >>> match_hostname_backport(server_certificate, host_name) >>> File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line >>> 168, in match_hostname_backport >>> raise ValueError("empty or no certificate") >>> ValueError: empty or no certificate >>> >>> Any ideas what I'm doing wrong? Any help would be greatly appreciated... >>> I've been struggling with openldap/python-ldap/python3-for 12 hours today!! >>> >> >> >> -- >> Have fun, >> gc >> >> > -- Have fun, gc -------------- next part -------------- An HTML attachment was scrubbed... URL: From richard-lists at esplins.org Tue Apr 29 23:30:20 2014 From: richard-lists at esplins.org (Richard Esplin) Date: Tue, 29 Apr 2014 15:30:20 -0600 Subject: [python3-ldap] Trouble with STARTTLS In-Reply-To: References: Message-ID: <2581207.6xhitS2p0r@richs.localnet.esplins.org> It worked for me to establish an SSL connection on port 636 using python3-ldap version 0.9.1 and Python 3.3. My code is below. I download the cert in advance, and save the path in the configuration file. I also pull things like the bind dn from the config file. I would get the error you report if my certificate was incorrect or I had an error in the path. It took me a few tries to get the CA cert as a PEM saved in the format the code needed at a path it could follow. Good luck, Richard ---- from .global_logging import logging from .global_config import config, config_dir import os import ldap3 as ldap import ssl def check_auth(username, password): try: # TLS object for TLS related options. Cert checking is disabled by default. # Use the CA cert, stored in the config directory # * extracted from the server with # openssl s_client -showcerts -connect :636 # * verify with # openssl verify .crt # * Cert should be a PEM cert_file = os.path.join(config_dir, config.get("LDAP", "cert_file")) tls_obj = ldap.Tls(ca_certs_file = cert_file, validate = ssl.CERT_REQUIRED) ldap_server = ldap.Server(config.get("LDAP", "ldap_server"), port = 636, use_ssl = True, tls = tls_obj) basedn = "uid=%s,%s,%s" % (username, config.get("LDAP", "bind_organisation"), config.get("LDAP", "domain_components")) ldap_conn = ldap.Connection(ldap_server, auto_bind = True, user = basedn, password = password, read_only = True) # TODO: Use the connection timeout in the config file ldap_conn.unbind() return True except ldap.LDAPException as e: logging.warning("LDAP connection failed. Exception: %s" %e) return False On Tuesday, April 29, 2014 00:04:07 Mark E. Haase wrote: > I really like python3-ldap. Much cleaner than building on top of OpenLDAP :) > > I can get TLS working on port 636, but I can't figure out how to get Start > TLS on port 389. Here's what I have so far (Python 2.7): > > 01 import ldap3 > 02 import os > 03 import ssl > 04 > 05 host = "ldap.*************.net" > 06 port = 389 > 07 username = "cn=admin,dc=*************,dc=net" > 08 password = "*************" > 09 base_path = os.path.dirname(os.path.realpath(__file__)) > 10 > 11 tls = ldap3.Tls(validate=ssl.CERT_REQUIRED, > ca_certs_file=os.path.join(base_path, "goodca")) > 12 ldap_server = ldap3.Server(host, port=port, use_ssl=False, tls=tls) > 13 ldap_handle = ldap3.Connection(ldap_server, user=username, > password=password) > 14 ldap_handle.open() > 15 ldap_handle.start_tls() > 16 ldap_handle.bind() > > I'm ~100% sure that "goodca" is not the problem, because I've validated it > with openssl s_client, gnutls-cli, ldapsearch, and python-ldap. It's PEM > encoded. When I run this example, I get this exception: > > mhaase at luci:~/luci/bin$ python test.py > Traceback (most recent call last): > File "test.py", line 15, in > ldap_handle.start_tls() > File "/usr/local/lib/python2.7/dist-packages/ldap3/core/connection.py", > line 535, in start_tls > if self.server.tls.start_tls(self): > File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line > 118, in start_tls > return self._start_tls(connection) > File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line > 121, in _start_tls > connection.socket = self.wrap_socket(connection, False) > File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line 91, > in wrap_socket > check_hostname(wrapped_socket, connection.server.host, self.valid_names) > File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line 206, > in check_hostname > match_hostname_backport(server_certificate, host_name) > File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line > 168, in match_hostname_backport > raise ValueError("empty or no certificate") > ValueError: empty or no certificate > > Any ideas what I'm doing wrong? Any help would be greatly appreciated... > I've been struggling with openldap/python-ldap/python3-for 12 hours today!! From python3ldap at gmail.com Tue May 20 19:33:53 2014 From: python3ldap at gmail.com (python3ldap) Date: Tue, 20 May 2014 19:33:53 +0200 Subject: [python3-ldap] python3-ldap 0.9.3 released - new Exception hierarchy and "raise_exceptions" connection mode Message-ID: Hello everybody, I've released the 0.9.3 version of python3-ldap. It includes many fixes and a few new features: This is the changelog: - Now the key in server.schema.attribute_type is the attribute name (was the oid) - Now the key in server.schema.object_classes is the class name (was the oid) - Added check_names to Connection definition to have the names of attributes and object class checked against the schema - Updated setuptools to 3.6 - Added wheel installation format - Added raise_exceptions mode for connection - Exception hierarchy reworked - Added locking to Server object (for multithreading) There is a major feature in this version, I've rewritten the Exception hierarchy and you can now use the Connection in a "raise_exceptions" mode, as suggested by Michael on this mailing list. The new hierarchy includes a LDAPException root class with two main branches: LDAPExceptionError and LDAPExceptionResult. The LDAPExceptionError contains 42 different exceptions that should help to understand what's wrong when you have an error. A few of these (including all the LDAPCommunicationError exceptions) have multiple inheritance either from the LDAPExceptionError and from specific Python exceptions. This is to let you choose to catch standard Python errors or the more detailed python3-ldap errors. The LDAPCommunicationError exceptions will be created at runtime and inherit the specific socket exception raised by the interpreter, so you can catch them with the specific socket.error or the more general LDAPCommunicationError. LDAPOperationResult (the other branch of LDAPException hierarchy) includes 48 exceptions, one for each possible error result (except RESULT_SUCCESS) specified in the LDAPv3 protocol. When you create a connection object with the "raise_exceptions" parameter set to True any LDAP operation will throw an exception of this class, subclassed to the specific LDAP result code exception. For example if you get an INVALID_DN_SYNTAX (result code 34) the connection will raise the LDAPInvalidDNSyntaxResult exception, with the following parameter: result, description, dn, message, response_type, and the whole response filled with the values received in the response of the LDAP operation. You can specify which result code you don't want to raise exceptions, default is : RESULT_COMPARE_FALSE, RESULT_COMPARE_TRUE, RESULT_REFERRAL (and of course RESULT_SUCCESS). You can change this behaviour in the ldap3 __init__.py package or at runtime modifying the ldap3.DO_NOT_RAISE_EXCEPTIONS list. The "raise_exceptions" mode is helpful if you want exceptions to flow up in the code and manage them at a upper level than the single operation level. This mode works in every kind of strategy, even in the ReusableStrategy (for connection pooling) where exceptions are trapped in the "effective" Connection thread and are sent back to the calling Connection object in the main (or another) thread. I admit that I don't use this kind of "flow up" exception handling so let me know if something is not working as expected. Another minor feature I added in this release is the "check_names" flag in the Connection object. If you set this parameter to True and the Server object has a get_info parameter of GET_SCHEMAINFO or GET_ALL_INFO assertions and filters attributes and object class names will be checked against the real schema of the server and the operation will not be performed if the attribute or object name is not defined in the schema. This kind of checking is requested by the LDAP RFCs but I've made it optional because it require extra-work (really a little work) to read the schema and check the assertions and the filter values. I've also added machinery to the Server object to work in a multi-threaded strategy. Last thing, I've included a "wheel" installation package that should be suitable for python2 and python3, let me know if you have problem with it. Have fun, gc The Exception Hierarchy: LDAPException LDAPExceptionError LDAPAttributeError (inherits also from AttributeError) LDAPBindError LDAPCertificateError LDAPChangesError (inherits also from ValueError) LDAPCommunicationError (all may inherit from socket.error) LDAPReferralError LDAPSessionTerminatedByServer LDAPSocketCloseError LDAPSocketOpenError LDAPSocketReceiveError LDAPSocketSendError LDAPUnknownRequestError LDAPUnknownResponseError LDAPConnectionIsReadOnlyError LDAPConnectionPoolNameIsMandatoryError LDAPConnectionPoolNotStartedError LDAPControlsError (inherits also from ValueError) LDAPEntryError LDAPInvalidDereferenceAliasesError (inherits also from ValueError) LDAPInvalidFilterError LDAPInvalidPort LDAPInvalidScopeError (inherits also from ValueError) LDAPInvalidServerError LDAPKeyError (inherits also from KeyError) LDAPLDIFError LDAPMetricsError LDAPObjectClassError (inherits also from ValueError) LDAPObjectError LDAPPasswordIsMandatoryError LDAPReaderError LDAPSASLBindInProgressError LDAPSASLMechanismNotSupportedError LDAPSASLPrepError LDAPSchemaError LDAPServerPoolError LDAPServerPoolExhaustedError LDAPSSLConfigurationError LDAPSSLNotSupportedError (inherits also from ImportError) LDAPStartTLSError LDAPTypeError LDAPUnknownAuthenticationMethodError LDAPUnknownStrategyError LDAPOperationResult LDAPAdminLimitExceededResult LDAPAffectMultipleDSASResult LDAPAliasDereferencingProblemResult LDAPAliasProblemResult LDAPAssertionFailedResult LDAPAttributeOrValueExistsResult LDAPAuthMethodNotSupportedResult LDAPAuthorizationDeniedResult LDAPBusyResult LDAPCanceledResult LDAPCannotCancelResult LDAPConfidentialityRequiredResult LDAPConstraintViolationResult LDAPEntryAlreadyExistsResult LDAPESyncRefreshRequiredResult LDAPInappropriateAuthenticationResult LDAPInappropriateMatchingResult LDAPInsufficientAccessRightsResult LDAPInvalidAttributeSyntaxResult LDAPInvalidCredentialsResult LDAPInvalidDNSyntaxResult LDAPLCUPInvalidDataResult LDAPLCUPReloadRequiredResult LDAPLCUPResourcesExhaustedResult LDAPLCUPSecurityViolationResult LDAPLCUPUnsupportedSchemeResult LDAPLoopDetectedResult LDAPNamingViolationResult LDAPNoSuchAttributeResult LDAPNoSuchObjectResult LDAPNoSuchOperationResult LDAPNotAllowedOnNotLeafResult LDAPNotAllowedOnRDNResult LDAPObjectClassModsProhibitedResult LDAPObjectClassViolationResult LDAPOperationsErrorResult LDAPOtherResult LDAPProtocolErrorResult LDAPReferralResult LDAPSASLBindInProgressResult LDAPSizeLimitExceededResult LDAPStrongerAuthRequiredResult LDAPTimeLimitExceededResult LDAPTooLateResult LDAPUnavailableCriticalExtensionResult LDAPUnavailableResult LDAPUndefinedAttributeTypeResult LDAPUnwillingToPerformResult I know, I should work on the docs to make a brief description of each of the exception and should generally improve the whole documentation. From richard-lists at esplins.org Tue May 20 20:16:27 2014 From: richard-lists at esplins.org (Richard Esplin) Date: Tue, 20 May 2014 12:16:27 -0600 Subject: [python3-ldap] python3-ldap 0.9.3 released - new Exception hierarchy and "raise_exceptions" connection mode In-Reply-To: References: Message-ID: <1761779.RToFjlR2jA@richs.localnet.esplins.org> This is great news! I am very excited about the exception hierarchy. That impressive list of exceptions should help a lot in debugging. Thank you for producing a great library and making it so easy to use. Richard On Tuesday, May 20, 2014 19:33:53 python3ldap wrote: > Hello everybody, > I've released the 0.9.3 version of python3-ldap. It includes many > fixes and a few new features: > > This is the changelog: > - Now the key in server.schema.attribute_type is the attribute > name (was the oid) > - Now the key in server.schema.object_classes is the class name > (was the oid) > - Added check_names to Connection definition to have the names of > attributes and object class checked against the schema > - Updated setuptools to 3.6 > - Added wheel installation format > - Added raise_exceptions mode for connection > - Exception hierarchy reworked > - Added locking to Server object (for multithreading) > > There is a major feature in this version, I've rewritten the Exception > hierarchy and you can now use the Connection in a "raise_exceptions" > mode, as suggested by Michael on this mailing list. From richard-lists at esplins.org Tue May 20 20:22:10 2014 From: richard-lists at esplins.org (Richard Esplin) Date: Tue, 20 May 2014 12:22:10 -0600 Subject: [python3-ldap] python3-ldap and Django Message-ID: <1627056.FlA5tLjsPW@richs.localnet.esplins.org> I am very impressed with python3-ldap. It is much more pythonic than the old python-ldap, which makes it easier to use. I am building an LDAP backed web site in Django. There are two modules I will need: * django-auth-ldap for authenticating a user against an LDAP back-end, * django-ldapdb for writing user changes back to LDAP. Both of these modules expect python-ldap. I am trying to decide the best way to get them to use python3-ldap: 1) Rewrite them to call python3-ldap 2) Work on the python3-ldap compat module so that it can drop in for python- ldap Option 1 seems like it will produce the cleanest code. Option 2 seems like it will be the most useful for other applications that expect python-ldap, and on-going maintenance of the modules that call them. I'm not sure which approach will be easiest. Is anyone else working on this? Does anyone have any wisdom, suggestions, opinions to share? Thanks, Richard From python3ldap at gmail.com Wed May 21 10:57:40 2014 From: python3ldap at gmail.com (python3ldap) Date: Wed, 21 May 2014 10:57:40 +0200 Subject: [python3-ldap] python3-ldap and Django In-Reply-To: <1627056.FlA5tLjsPW@richs.localnet.esplins.org> References: <1627056.FlA5tLjsPW@richs.localnet.esplins.org> Message-ID: Hello Richard, thanks for your message. Regarding your question on python-ldap compatability I'm starting to write some test code for the "drop in" but I can't assure I will get something suitable for a production environment. The main issue is that python-ldap is a wrapper to the openldap C client library, so I can't check thoroughly how the C code manages the sending and receiving of data. I think that I should be able to wirte a "compat" package that translates the python-ldap signature to python3-ldap, but I think that the result depends on how the python-ldap code is used in the application. So in your case I prefer the first option (rewrite django-auth-ldap and django-ldapdb) for python3-ldap because you can reuse it in any other django based application. Anyway I hope to have something working in a month or two. Bye, Giovanni Have fun, gc 2014-05-20 20:22 GMT+02:00 Richard Esplin : > I am very impressed with python3-ldap. It is much more pythonic than the old > python-ldap, which makes it easier to use. > > I am building an LDAP backed web site in Django. There are two modules I will > need: > > * django-auth-ldap for authenticating a user against an LDAP back-end, > * django-ldapdb for writing user changes back to LDAP. > > Both of these modules expect python-ldap. I am trying to decide the best way > to get them to use python3-ldap: > > 1) Rewrite them to call python3-ldap > 2) Work on the python3-ldap compat module so that it can drop in for python- > ldap > > Option 1 seems like it will produce the cleanest code. Option 2 seems like it > will be the most useful for other applications that expect python-ldap, and > on-going maintenance of the modules that call them. I'm not sure which > approach will be easiest. > > Is anyone else working on this? > > Does anyone have any wisdom, suggestions, opinions to share? > > Thanks, > > Richard > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap From jcasale at activenetwerx.com Wed May 21 14:44:27 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Wed, 21 May 2014 12:44:27 +0000 Subject: [python3-ldap] ldif producer strategy Message-ID: <7a045c39d5c5485ebab05db60ee413b1@exch.activenetwerx.com> It looks like the connection response only maintains the last operation applied when utilizing this strategy for multiple changes. Under this scenario, the version header is written out each time so accumulating changes forces disk access for each set and string manipulation to reformat. This might be less than optimal when building change sets in the 100k+ range. Currently I am cherry picking all sorts of code out to produce my own methods which is not very maintainable. What do you think Giovanni? Thanks, jlc From python3ldap at gmail.com Wed May 28 15:03:51 2014 From: python3ldap at gmail.com (python3ldap) Date: Wed, 28 May 2014 15:03:51 +0200 Subject: [python3-ldap] python3-ldap 0.9.3.1 is out. Message-ID: Hello, version 0.9.3.1 is out. I made some enhancement in the LDIFProducer strategy. It's now possibile send all the LDIF output to a file and the order of the lines in the output can be customized (for example if you want the 'givenNane' always before the 'cn'). It's also possible to specify a custom line separator (for using the ldif on a different platform). The same enanchements are available in the response_to_ldif() method while searching objects. Please have a look at https://pythonhosted.org/python3-ldap/ldif.html if you're interested in this topic. I've also fixed an annoying bug that slow down the Server instantiation when the scheme was specified in the server name. This is the changelog for 0.9.3.1: - Added stream capability to LDIFProducer strategy - Customizable line separator for ldif output - Customizable sorting order in ldif output - object_class parameter is now optional in connection.add() - Fixed objectClass attribute case sensitive dependency in add operation - Added stream capability to response_to_ldif() while searching Have fun, gc From tsk133 at my.utsa.edu Thu Jun 12 22:26:16 2014 From: tsk133 at my.utsa.edu (David Noriega) Date: Thu, 12 Jun 2014 15:26:16 -0500 Subject: [python3-ldap] TLS issue Message-ID: On Windows 7 with Python 3.4.1 and python3-ldap 0.9.3.3 I'm trying to create a TLS connection to an ldap server over port 389 and I provide the CA cert file(in pem format) but I get the following: Traceback (most recent call last): File "C:\Python34\lib\site-packages\ldap3\strategy\baseStrategy.py", line 134, in _open_socket self.connection.socket = self.connection.server.tls.wrap_socket(self.connect ion, do_handshake=True) File "C:\Python34\lib\site-packages\ldap3\core\tls.py", line 89, in wrap_socke t wrapped_socket = ssl.wrap_socket(connection.socket, keyfile=self.private_key _file, certfile=self.certificate_file, server_side=False, cert_reqs=self.validat e, ssl_version=self.version, ca_certs=self.ca_certs_file, do_handshake_on_connec t=do_handshake) File "C:\Python34\lib\ssl.py", line 888, in wrap_socket ciphers=ciphers) File "C:\Python34\lib\ssl.py", line 511, in __init__ self._context.load_verify_locations(ca_certs) ssl.SSLError: unknown error (_ssl.c:2734) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "", line 1, in File "C:\Python34\lib\site-packages\ldap3\core\connection.py", line 174, in __ init__ self.open() File "C:\Python34\lib\site-packages\ldap3\strategy\syncWait.py", line 49, in o pen BaseStrategy.open(self, reset_usage) File "C:\Python34\lib\site-packages\ldap3\strategy\baseStrategy.py", line 88, in open self._open_socket(self.connection.server.ssl) File "C:\Python34\lib\site-packages\ldap3\strategy\baseStrategy.py", line 139, in _open_socket raise communication_exception_factory(LDAPSocketOpenError, e)(self.connectio n.last_error) ldap3.core.exceptions.LDAPSocketOpenError: ('socket ssl wrapping error: unknown error (_ssl.c:2734)',) -------------- next part -------------- An HTML attachment was scrubbed... URL: From python3ldap at gmail.com Fri Jun 13 00:24:11 2014 From: python3ldap at gmail.com (python3ldap) Date: Fri, 13 Jun 2014 00:24:11 +0200 Subject: [python3-ldap] TLS issue In-Reply-To: References: Message-ID: Hi David, are you sure that you must connect to the 389 port? Usually tls is on 636 port. If 389 is right probably the ca file is wrong. In that case i need some more info. You should try to connect without CA and without verifying the certificate chain. Let me know. Bye, Giovanni Il gioved? 12 giugno 2014, David Noriega ha scritto: > On Windows 7 with Python 3.4.1 and python3-ldap 0.9.3.3 > > I'm trying to create a TLS connection to an ldap server over port 389 and > I provide the CA cert file(in pem format) but I get the following: > > Traceback (most recent call last): > File "C:\Python34\lib\site-packages\ldap3\strategy\baseStrategy.py", > line 134, > in _open_socket > self.connection.socket = > self.connection.server.tls.wrap_socket(self.connect > ion, do_handshake=True) > File "C:\Python34\lib\site-packages\ldap3\core\tls.py", line 89, in > wrap_socke > t > wrapped_socket = ssl.wrap_socket(connection.socket, > keyfile=self.private_key > _file, certfile=self.certificate_file, server_side=False, > cert_reqs=self.validat > e, ssl_version=self.version, ca_certs=self.ca_certs_file, > do_handshake_on_connec > t=do_handshake) > File "C:\Python34\lib\ssl.py", line 888, in wrap_socket > ciphers=ciphers) > File "C:\Python34\lib\ssl.py", line 511, in __init__ > self._context.load_verify_locations(ca_certs) > ssl.SSLError: unknown error (_ssl.c:2734) > > During handling of the above exception, another exception occurred: > > Traceback (most recent call last): > File "", line 1, in > File "C:\Python34\lib\site-packages\ldap3\core\connection.py", line 174, > in __ > init__ > self.open() > File "C:\Python34\lib\site-packages\ldap3\strategy\syncWait.py", line > 49, in o > pen > BaseStrategy.open(self, reset_usage) > File "C:\Python34\lib\site-packages\ldap3\strategy\baseStrategy.py", > line 88, > in open > self._open_socket(self.connection.server.ssl) > File "C:\Python34\lib\site-packages\ldap3\strategy\baseStrategy.py", > line 139, > in _open_socket > raise communication_exception_factory(LDAPSocketOpenError, > e)(self.connectio > n.last_error) > ldap3.core.exceptions.LDAPSocketOpenError: ('socket ssl wrapping error: > unknown > error (_ssl.c:2734)',) > -- Have fun, gc -------------- next part -------------- An HTML attachment was scrubbed... URL: From tsk133 at my.utsa.edu Fri Jun 20 07:49:55 2014 From: tsk133 at my.utsa.edu (David Noriega) Date: Fri, 20 Jun 2014 00:49:55 -0500 Subject: [python3-ldap] TLS issue In-Reply-To: References: Message-ID: To recap what happened off camera, you had me try out using raw sockets to connect to the ssl ldap port 636, like so: import socket import ssl HOST = "your_host" PORT = 636 sock = socket.socket() sock.connect((HOST, PORT)) sock = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_REQUIRED, ca_certs="your_ca_certs_file") This works on linux, both python 2.6 and 3.2, but on windows it fails. I tried 3.4.1, and going back with 3.3 and 3.2. With it working on Linux, I could use sock.getpeercert() to return the server certificate information. But this socket test got me thinking and I came across this on stackoverflow: http://stackoverflow.com/questions/19145097/getting-certificate-chain-with-python-3-3-ssl-module I modified that code slightly to use PROTOCOL_TLSv1 and CERT_REQUIRED. This works on linux as is, but again fails on windows. Reading deeper into the ssl docs, I found SSLContext.load_default_certs() which got me thinking about the differences between Windows and Linux. Windows has a central certificate store. Using this method http://community.spiceworks.com/how_to/show/1839-installing-self-signed-ca-certificate-in-windows, I imported my CA cert into Windows' cert store. I modified the code again to not use SSLContext.load_verify_locations() but instead load_default_certs() and this time it works. On Tue, Jun 17, 2014 at 12:15 AM, Python3-ldap wrote: > Hi David, this seem a problem with the python ssl module, it raise an > unknown error when trying to verify the ca cert. Are you sure that the > certificate ca format is PEM and contains only the public key of your ca > chain? Could you send me the certificate ca (it includes only the public > key, so it safe to send) so I can try it in my lab to see where the problem > is. > > Bye, > Giovanni > > ------------------------------ > Da: David Noriega > Inviato: ?17/?06/?2014 00.38 > A: python3ldap > Oggetto: Re: [python3-ldap] TLS issue > > Its the same for either cert required or none. I have a secondary ldap > server and tried against it, same thing. Even tried to test if there was a > difference between 32bit and 64bit, same thing. > >>> c.open() > >>> c.start_tls() > Traceback (most recent call last): > File "", line 1, in > c.start_tls() > File "C:\Python34\lib\site-packages\ldap3\core\connection.py", line 584, > in start_tls > if self.server.tls.start_tls(self): > File "C:\Python34\lib\site-packages\ldap3\core\tls.py", line 121, in > start_tls > return self._start_tls(connection) > File "C:\Python34\lib\site-packages\ldap3\core\tls.py", line 124, in > _start_tls > connection.socket = self.wrap_socket(connection, True) > File "C:\Python34\lib\site-packages\ldap3\core\tls.py", line 89, in > wrap_socket > wrapped_socket = ssl.wrap_socket(connection.socket, > keyfile=self.private_key_file, certfile=self.certificate_file, > server_side=False, cert_reqs=self.validate, ssl_version=self.version, > ca_certs=self.ca_certs_file, do_handshake_on_connect=do_handshake) > File "C:\Python34\lib\ssl.py", line 888, in wrap_socket > ciphers=ciphers) > File "C:\Python34\lib\ssl.py", line 511, in __init__ > self._context.load_verify_locations(ca_certs) > ssl.SSLError: unknown error (_ssl.c:2734) > > > > > On Sun, Jun 15, 2014 at 10:34 AM, python3ldap > wrote: > >> Hi David, >> this seem a ssl problem. Can you try the following with a good ca and >> then with a WRONG ca cert file? >> >> import ssl >> from ladp3 import Server, Connection, Tls >> t = Tls(ca_cert_file='your_ca_file', validate=ssl.CERT_REQUIRED) >> s = Server('your_server', tls = t) >> c = Connection(s, user='your_user', password='your_password') >> c.open() >> c.start_tls() >> c.bind() >> c.close() >> >> Then you should do the same with validate set to ssl.CERT_NONE. >> >> Can you send me back the result of each statement? >> >> Bye, >> Giovanni >> >> >> 2014-06-13 19:45 GMT+02:00 David Noriega : >> > Yes, port 389 is correct, this is how we use it. Its explained here: >> > http://www.openldap.org/faq/data/cache/185.html >> > >> > I've been able to use the older python-ldap on 2.x previously, so I >> know it >> > can work. >> > >> > Here I can get some simple info from ldap: >> >>>> import ldap3 >> >>>> s = ldap3.Server('X.X.X.X', port=389, get_info=ldap3.GET_ALL_INFO) >> >>>> c = ldap3.Connection(s, auto_bind=True) >> >>>> print(s.info) >> > DSA info (from DSE): >> > >> > Supported LDAP Versions: 3 >> > >> > Naming Contexts: >> > >> > dc=X,dc=X,dc=X >> > >> > Supported Controls: >> > >> > 1.3.6.1.4.1.4203.1.9.1.1 - LDAP content synchronization - Control - >> > RFC4533 >> > >> > 2.16.840.1.113730.3.4.18 - Proxy Authorization Control - Control - >> > RFC6171 >> > >> > 2.16.840.1.113730.3.4.2 - ManageDsaIT - Control - RFC3296 >> > >> > 1.3.6.1.4.1.4203.1.10.1 - Subentries - Control - RFC3672 >> > >> > 1.2.840.113556.1.4.319 - LDAP Simple Paged Results - Control - >> RFC2696 >> > >> > 1.2.826.0.1.3344810.2.3 - Matched Values - Control - RFC3876 >> > >> > 1.3.6.1.1.13.2 - LDAP Post-read - Control - RFC4527 >> > >> > 1.3.6.1.1.13.1 - LDAP Pre-read - Control - RFC4527 >> > >> > 1.3.6.1.1.12 - Assertion - Control - RFC4528 >> > >> > Supported Extensions: >> > >> > 1.3.6.1.4.1.1466.20037 - StartTLS - Extension - RFC4511-RFC4513 >> > >> > 1.3.6.1.4.1.4203.1.11.1 - Modify Password - Extension - RFC3062 >> > >> > 1.3.6.1.4.1.4203.1.11.3 - Who am I - Extension - RFC4532 >> > >> > 1.3.6.1.1.8 - Cancel Operation - Extension - RFC3909 >> > >> > Supported Features: >> > >> > 1.3.6.1.1.14 - Modify-Increment - Feature - RFC4525 >> > >> > 1.3.6.1.4.1.4203.1.5.1 - All Op Attrs - Feature - RFC3673 >> > >> > 1.3.6.1.4.1.4203.1.5.2 - OC AD Lists - Feature - RFC4529 >> > >> > 1.3.6.1.4.1.4203.1.5.3 - True/False filters - Feature - RFC4526 >> > >> > 1.3.6.1.4.1.4203.1.5.4 - Language Tag Options - Feature - RFC3866 >> > >> > 1.3.6.1.4.1.4203.1.5.5 - language Range Options - Feature - RFC3866 >> > >> > Supported SASL Mechanisms: >> > >> > CRAM-MD5, GSSAPI, DIGEST-MD5 >> > >> > Schema Entry: >> > >> > cn=Subschema >> > >> > Other: >> > >> > objectClass: >> > >> > top >> > >> > OpenLDAProotDSE >> > >> > monitorContext: >> > >> > cn=Monitor >> > >> > configContext: >> > >> > cn=config >> > >> > structuralObjectClass: >> > >> > OpenLDAProotDSE >> > >> > entryDN: >> > >> > If I try to bind via AUTH_SIMPLE, the server responds as expected with >> > confidentiality required message. I then try again by setting up a Tls >> > object and I've tried with all CERT_ options but get the same error. >> This CA >> > cert file is good because its currently used by all my systems for ldap >> > authentication. >> > >> > >> > >> > On Thu, Jun 12, 2014 at 5:24 PM, python3ldap wrote: > Hi David, > are you sure that you must connect to the 389 port? Usually tls is on > 636 port. If 389 is right probably the ca file is wrong. In that case > i need some more info. You should try to connect without CA and > without verifying the certificate chain. > > Let me know. > Bye, > Giovanni > > > Il gioved? 12 giugno 2014, David Noriega ha scritto: > > On Windows 7 with Python 3.4.1 and python3-ldap 0.9.3.3 >> >> I'm trying to create a TLS connection to an ldap server over port 389 and >> I provide the CA cert file(in pem format) but I get the following: >> >> Traceback (most recent call last): >> File "C:\Python34\lib\site-packages\ldap3\strategy\baseStrategy.py", >> line 134, >> in _open_socket >> self.connection.socket = >> self.connection.server.tls.wrap_socket(self.connect >> ion, do_handshake=True) >> File "C:\Python34\lib\site-packages\ldap3\core\tls.py", line 89, in >> wrap_socke >> t >> wrapped_socket = ssl.wrap_socket(connection.socket, >> keyfile=self.private_key >> _file, certfile=self.certificate_file, server_side=False, >> cert_reqs=self.validat >> e, ssl_version=self.version, ca_certs=self.ca_certs_file, >> do_handshake_on_connec >> t=do_handshake) >> File "C:\Python34\lib\ssl.py", line 888, in wrap_socket >> ciphers=ciphers) >> File "C:\Python34\lib\ssl.py", line 511, in __init__ >> self._context.load_verify_locations(ca_certs) >> ssl.SSLError: unknown error (_ssl.c:2734) >> >> During handling of the above exception, another exception occurred: >> >> Traceback (most recent call last): >> File "", line 1, in >> File "C:\Python34\lib\site-packages\ldap3\core\connection.py", line >> 174, in __ >> init__ >> self.open() >> File "C:\Python34\lib\site-packages\ldap3\strategy\syncWait.py", line >> 49, in o >> pen >> BaseStrategy.open(self, reset_usage) >> File "C:\Python34\lib\site-packages\ldap3\strategy\baseStrategy.py", >> line 88, >> in open >> self._open_socket(self.connection.server.ssl) >> File "C:\Python34\lib\site-packages\ldap3\strategy\baseStrategy.py", >> line 139, >> in _open_socket >> raise communication_exception_factory(LDAPSocketOpenError, >> e)(self.connectio >> n.last_error) >> ldap3.core.exceptions.LDAPSocketOpenError: ('socket ssl wrapping error: >> unknown >> error (_ssl.c:2734)',) >> > > > -- > Have fun, > gc > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tsk133 at my.utsa.edu Fri Jun 20 07:50:55 2014 From: tsk133 at my.utsa.edu (David Noriega) Date: Fri, 20 Jun 2014 00:50:55 -0500 Subject: [python3-ldap] TLS issue In-Reply-To: References: Message-ID: I've never done this before, but I thought I'd go into the code and see how things work and created this patch. My hack modifies tls.py in ldap3.core to use ssl.SSLContext.wrap_socket instead of ssl.wrap_socket On Fri, Jun 20, 2014 at 12:49 AM, David Noriega wrote: > To recap what happened off camera, you had me try out using raw sockets to > connect to the ssl ldap port 636, like so: > > import socket > import ssl > HOST = "your_host" > PORT = 636 > sock = socket.socket() > sock.connect((HOST, PORT)) > sock = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_REQUIRED, > ca_certs="your_ca_certs_file") > > This works on linux, both python 2.6 and 3.2, but on windows it fails. I > tried 3.4.1, and going back with 3.3 and 3.2. With it working on Linux, I > could use sock.getpeercert() to return the server certificate information. > But this socket test got me thinking and I came across this on > stackoverflow: > http://stackoverflow.com/questions/19145097/getting-certificate-chain-with-python-3-3-ssl-module > > I modified that code slightly to use PROTOCOL_TLSv1 and CERT_REQUIRED. > This works on linux as is, but again fails on windows. Reading deeper into > the ssl docs, I found SSLContext.load_default_certs() which got me thinking > about the differences between Windows and Linux. Windows has a central > certificate store. Using this method > http://community.spiceworks.com/how_to/show/1839-installing-self-signed-ca-certificate-in-windows, > I imported my CA cert into Windows' cert store. I modified the code again > to not use SSLContext.load_verify_locations() but instead > load_default_certs() and this time it works. > > > > > On Tue, Jun 17, 2014 at 12:15 AM, Python3-ldap > wrote: > >> Hi David, this seem a problem with the python ssl module, it raise an >> unknown error when trying to verify the ca cert. Are you sure that the >> certificate ca format is PEM and contains only the public key of your ca >> chain? Could you send me the certificate ca (it includes only the public >> key, so it safe to send) so I can try it in my lab to see where the problem >> is. >> >> Bye, >> Giovanni >> >> ------------------------------ >> Da: David Noriega >> Inviato: ?17/?06/?2014 00.38 >> A: python3ldap >> Oggetto: Re: [python3-ldap] TLS issue >> >> Its the same for either cert required or none. I have a secondary ldap >> server and tried against it, same thing. Even tried to test if there was a >> difference between 32bit and 64bit, same thing. >> >>> c.open() >> >>> c.start_tls() >> Traceback (most recent call last): >> File "", line 1, in >> c.start_tls() >> File "C:\Python34\lib\site-packages\ldap3\core\connection.py", line >> 584, in start_tls >> if self.server.tls.start_tls(self): >> File "C:\Python34\lib\site-packages\ldap3\core\tls.py", line 121, in >> start_tls >> return self._start_tls(connection) >> File "C:\Python34\lib\site-packages\ldap3\core\tls.py", line 124, in >> _start_tls >> connection.socket = self.wrap_socket(connection, True) >> File "C:\Python34\lib\site-packages\ldap3\core\tls.py", line 89, in >> wrap_socket >> wrapped_socket = ssl.wrap_socket(connection.socket, >> keyfile=self.private_key_file, certfile=self.certificate_file, >> server_side=False, cert_reqs=self.validate, ssl_version=self.version, >> ca_certs=self.ca_certs_file, do_handshake_on_connect=do_handshake) >> File "C:\Python34\lib\ssl.py", line 888, in wrap_socket >> ciphers=ciphers) >> File "C:\Python34\lib\ssl.py", line 511, in __init__ >> self._context.load_verify_locations(ca_certs) >> ssl.SSLError: unknown error (_ssl.c:2734) >> >> >> >> >> On Sun, Jun 15, 2014 at 10:34 AM, python3ldap >> wrote: >> >>> Hi David, >>> this seem a ssl problem. Can you try the following with a good ca and >>> then with a WRONG ca cert file? >>> >>> import ssl >>> from ladp3 import Server, Connection, Tls >>> t = Tls(ca_cert_file='your_ca_file', validate=ssl.CERT_REQUIRED) >>> s = Server('your_server', tls = t) >>> c = Connection(s, user='your_user', password='your_password') >>> c.open() >>> c.start_tls() >>> c.bind() >>> c.close() >>> >>> Then you should do the same with validate set to ssl.CERT_NONE. >>> >>> Can you send me back the result of each statement? >>> >>> Bye, >>> Giovanni >>> >>> >>> 2014-06-13 19:45 GMT+02:00 David Noriega : >>> > Yes, port 389 is correct, this is how we use it. Its explained here: >>> > http://www.openldap.org/faq/data/cache/185.html >>> > >>> > I've been able to use the older python-ldap on 2.x previously, so I >>> know it >>> > can work. >>> > >>> > Here I can get some simple info from ldap: >>> >>>> import ldap3 >>> >>>> s = ldap3.Server('X.X.X.X', port=389, get_info=ldap3.GET_ALL_INFO) >>> >>>> c = ldap3.Connection(s, auto_bind=True) >>> >>>> print(s.info) >>> > DSA info (from DSE): >>> > >>> > Supported LDAP Versions: 3 >>> > >>> > Naming Contexts: >>> > >>> > dc=X,dc=X,dc=X >>> > >>> > Supported Controls: >>> > >>> > 1.3.6.1.4.1.4203.1.9.1.1 - LDAP content synchronization - Control - >>> > RFC4533 >>> > >>> > 2.16.840.1.113730.3.4.18 - Proxy Authorization Control - Control - >>> > RFC6171 >>> > >>> > 2.16.840.1.113730.3.4.2 - ManageDsaIT - Control - RFC3296 >>> > >>> > 1.3.6.1.4.1.4203.1.10.1 - Subentries - Control - RFC3672 >>> > >>> > 1.2.840.113556.1.4.319 - LDAP Simple Paged Results - Control - >>> RFC2696 >>> > >>> > 1.2.826.0.1.3344810.2.3 - Matched Values - Control - RFC3876 >>> > >>> > 1.3.6.1.1.13.2 - LDAP Post-read - Control - RFC4527 >>> > >>> > 1.3.6.1.1.13.1 - LDAP Pre-read - Control - RFC4527 >>> > >>> > 1.3.6.1.1.12 - Assertion - Control - RFC4528 >>> > >>> > Supported Extensions: >>> > >>> > 1.3.6.1.4.1.1466.20037 - StartTLS - Extension - RFC4511-RFC4513 >>> > >>> > 1.3.6.1.4.1.4203.1.11.1 - Modify Password - Extension - RFC3062 >>> > >>> > 1.3.6.1.4.1.4203.1.11.3 - Who am I - Extension - RFC4532 >>> > >>> > 1.3.6.1.1.8 - Cancel Operation - Extension - RFC3909 >>> > >>> > Supported Features: >>> > >>> > 1.3.6.1.1.14 - Modify-Increment - Feature - RFC4525 >>> > >>> > 1.3.6.1.4.1.4203.1.5.1 - All Op Attrs - Feature - RFC3673 >>> > >>> > 1.3.6.1.4.1.4203.1.5.2 - OC AD Lists - Feature - RFC4529 >>> > >>> > 1.3.6.1.4.1.4203.1.5.3 - True/False filters - Feature - RFC4526 >>> > >>> > 1.3.6.1.4.1.4203.1.5.4 - Language Tag Options - Feature - RFC3866 >>> > >>> > 1.3.6.1.4.1.4203.1.5.5 - language Range Options - Feature - RFC3866 >>> > >>> > Supported SASL Mechanisms: >>> > >>> > CRAM-MD5, GSSAPI, DIGEST-MD5 >>> > >>> > Schema Entry: >>> > >>> > cn=Subschema >>> > >>> > Other: >>> > >>> > objectClass: >>> > >>> > top >>> > >>> > OpenLDAProotDSE >>> > >>> > monitorContext: >>> > >>> > cn=Monitor >>> > >>> > configContext: >>> > >>> > cn=config >>> > >>> > structuralObjectClass: >>> > >>> > OpenLDAProotDSE >>> > >>> > entryDN: >>> > >>> > If I try to bind via AUTH_SIMPLE, the server responds as expected with >>> > confidentiality required message. I then try again by setting up a Tls >>> > object and I've tried with all CERT_ options but get the same error. >>> This CA >>> > cert file is good because its currently used by all my systems for ldap >>> > authentication. >>> > >>> > >>> > >>> >> > > On Thu, Jun 12, 2014 at 5:24 PM, python3ldap > wrote: > >> Hi David, >> are you sure that you must connect to the 389 port? Usually tls is on >> 636 port. If 389 is right probably the ca file is wrong. In that case >> i need some more info. You should try to connect without CA and >> without verifying the certificate chain. >> >> Let me know. >> Bye, >> Giovanni >> >> >> Il gioved? 12 giugno 2014, David Noriega ha scritto: >> >> On Windows 7 with Python 3.4.1 and python3-ldap 0.9.3.3 >>> >>> I'm trying to create a TLS connection to an ldap server over port 389 >>> and I provide the CA cert file(in pem format) but I get the following: >>> >>> Traceback (most recent call last): >>> File "C:\Python34\lib\site-packages\ldap3\strategy\baseStrategy.py", >>> line 134, >>> in _open_socket >>> self.connection.socket = >>> self.connection.server.tls.wrap_socket(self.connect >>> ion, do_handshake=True) >>> File "C:\Python34\lib\site-packages\ldap3\core\tls.py", line 89, in >>> wrap_socke >>> t >>> wrapped_socket = ssl.wrap_socket(connection.socket, >>> keyfile=self.private_key >>> _file, certfile=self.certificate_file, server_side=False, >>> cert_reqs=self.validat >>> e, ssl_version=self.version, ca_certs=self.ca_certs_file, >>> do_handshake_on_connec >>> t=do_handshake) >>> File "C:\Python34\lib\ssl.py", line 888, in wrap_socket >>> ciphers=ciphers) >>> File "C:\Python34\lib\ssl.py", line 511, in __init__ >>> self._context.load_verify_locations(ca_certs) >>> ssl.SSLError: unknown error (_ssl.c:2734) >>> >>> During handling of the above exception, another exception occurred: >>> >>> Traceback (most recent call last): >>> File "", line 1, in >>> File "C:\Python34\lib\site-packages\ldap3\core\connection.py", line >>> 174, in __ >>> init__ >>> self.open() >>> File "C:\Python34\lib\site-packages\ldap3\strategy\syncWait.py", line >>> 49, in o >>> pen >>> BaseStrategy.open(self, reset_usage) >>> File "C:\Python34\lib\site-packages\ldap3\strategy\baseStrategy.py", >>> line 88, >>> in open >>> self._open_socket(self.connection.server.ssl) >>> File "C:\Python34\lib\site-packages\ldap3\strategy\baseStrategy.py", >>> line 139, >>> in _open_socket >>> raise communication_exception_factory(LDAPSocketOpenError, >>> e)(self.connectio >>> n.last_error) >>> ldap3.core.exceptions.LDAPSocketOpenError: ('socket ssl wrapping error: >>> unknown >>> error (_ssl.c:2734)',) >>> >> >> >> -- >> Have fun, >> gc >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: tls.py.patch Type: application/octet-stream Size: 2961 bytes Desc: not available URL: From python3ldap at gmail.com Wed Jul 2 04:25:29 2014 From: python3ldap at gmail.com (python3ldap) Date: Wed, 2 Jul 2014 04:25:29 +0200 Subject: [python3-ldap] python3-ldap version 0.9.4 is released Message-ID: Hello everybody, I've released the 0.9.4 version of python3-ldap. There are two major implementation in this release: a simple extended operation framework and the use of the ssl.SSLContext standard library class (from python 3.4 onward). There is a new namespace ldap3.extend that contains standard extended operation. You don't need to access it but you can find all the defined extended operation in the extend attribute of the connection. This attribute is quite peculiar, it has a shallow hierarchy of the extended operations defined in python3-ldap. For now the structure is the following: connection.extend. connection.extend.standard. connection.extend.standard.who_am_i() connection.extend.standard.modify_password(user, old_password, new_password) connection.extend.novell connection.extend.novell.get_bind_db() Just call the extend operation in the usual way, for example: c = Connection(....) c.bind() i_am = c.extend.standard.who_am_i() The payload of these extended operation is properly encoded and decoded. When available you should get the response value as the return value of the function and as an additional field of the result dictionary I will add addtional extended operation as the library evolves. The use of ssl.SSLContext make tls operation more flexible, It now integrates with the system wide Certification Authorities and also ensure that there are "reasonable" security default when using the tls layer. It's now also possible to specify a file system path containing the CA file or even pass certificate data "on the fly". When defining the Tls object you have the following parameters available: ca_cert_file: the usual link to the certification authority chain of certificates ca_cert_path: a link to a path containing the certification authorities certificates (reashed, as expected by OpenSSL) ca_cert_data: CA certificate data stored in memory if you leave all these parameter to None the SSLContext will use the system wide certificate store (ssl path on linux, CA stores on Windows) If the SSLContext is not available the library will fall back to the ssl wrapped socket mechanism. This is the changelog for 0.9.4: * 0.9.4 2014.07.02 - when running in python 3.4 or newer now Tls class uses SSLContext object with default secure setting - added parameters ca_certs_path, ca_certs_data, local_private_key_password to Tls object creation, valid when using SSLContext - in python 3.4 or newer the system CA certificates configuration can be used (just leave ca_cert_file, ca_certs_path and ca_certs_data set to None) - removed TLSv1 as default for Tls connection - upgraded backported ssl function from python 3.4.1 when using with python 2 - when creating a connection server can now be a string, the name of the server to connect in cleartext on default port 389 - fixed bug in escape_bytes - attributes parameter in search can be a tuple - check_names parameter in connection now defaults to True (so if schema info is available attribute and class name will be checked when performing LDAP operations) - remove the connection.close() method - you must use connection.unbind() - new exception LDAPExtensionError for signaling when the requestValue of extended operation is of unknown ASN1 type - exiting connection manager doesn't raise exception if unbind is not successful (needed in long operations) - new extended operation: modify_password (RFC3062) - new extended operation: who_am_i (RFC4532) - new extended operation: get_bind_dn (Novell) - updated setuptools to version 5.3 Have fun, Giovanni From python3ldap at gmail.com Wed Jul 2 10:00:25 2014 From: python3ldap at gmail.com (python3ldap) Date: Wed, 2 Jul 2014 10:00:25 +0200 Subject: [python3-ldap] python3-ldap 0.9.4.1 - moving to bitbucket + mercurial Message-ID: python 0.9.4 was missing the ldap3.extend package. I've included it in the 0.9.4.1. Sorry for the inconvenience. I'm moving the project from Assembla repository. Assembla is a very good repository for private projects with many tools for agile developments but it's quite hard to use it for an open source project. I'll move to Bitbucket + mercurial in the next days. Bye, Giovanni From python3ldap at gmail.com Thu Jul 3 02:00:09 2014 From: python3ldap at gmail.com (python3ldap) Date: Thu, 3 Jul 2014 02:00:09 +0200 Subject: [python3-ldap] Moved python3-ldap source repository to Bitbucket Message-ID: Hello, version 0.9.4.2 is available, on pypi (as usual), I've moved to Bitbucket + Mercurial. The new repository URL is https://bitbucket.org/python3ldap/python3-ldap. You can issue a ticket at https://bitbucket.org/python3ldap/python3-ldap/issues . Bye, Giovanni From python3ldap at gmail.com Tue Jul 22 00:52:18 2014 From: python3ldap at gmail.com (python3ldap) Date: Tue, 22 Jul 2014 00:52:18 +0200 Subject: [python3-ldap] Python3-ldap 0.9.5 released Message-ID: Hello everybody. Python3-ldap 0.9.5 has just been released. With this version I thnk that the compliance to LDAP RFCs is (almost) done.I think now that I must tune the library and fix the bugs to (slowly) approach version 1,0. It includes three major (at least for me) enhancement: a. compliance with ivp6; b. 'checked_attributes' in search response; c. generator paged search a) Robert Tasarz helped me to fix the library to properly works in ipv6 only environment. I have not a IPv5 lab where to test, so I'm grateful to him for his work.o b) Checked attributes is the "missing" feature for the library to be really compliant with latest LDAP RFCs. It checks the ldap syntax of the atttributes defined in schema and returns a properly formatted entry result while performing searches. This means that if you have an attributes specified as GUID in the server schema you will get the properly formatted GUID value (for example '012381d3-3b1c-904f-b29a-012381d33b1c') in the connection.response[0]['checked_attributes'] key dictionary instead of a sequence of bytes. Or if you request an attribute defined as an Interger in the schema you will get the value already converted to int. Furthermore for attributes defined as single valued in schema you will get the value instead of a list of values (that would always be one sized). To activate this feature you must set the get info to GET_SCHEMA_INFO or GET_ALL_INFO value when defining the server object and the 'check_names' attributes to True in the Connection object (this is True by default starting from 0.9.4). There are a few of standard formatters defined in the library, most of them are defined in the relevants RFCs: format_unicode # returns an unicode object in Python 2 and a string in Python 3 format_integer # returns an integer format_binary # returns a bytes() sequence format_uuid # returns a GUID (UUID) as specified in RFC 4122 - byte order is big endian format_uuid_le # same as above but byte order is little endian format_boolean # returns a boolean format_time # returns a datetime object (with properly defined timezone, or UTC if timezone is not specified) as defined in RFC 4517 You can even define your custom formatter for specific purposes. Just pass a dictionary in the format {'identifier': callable} in the 'formatter' parameter of the Server object. The callable must be able to receive a single byte value and convert it the relevant object or class instance. The resolution order of the format feature is the following: Custom formatters have precedence over standard formatter. In each category (from highest to lowest): 1. attribute name 2. attribute oid(from schema) 3. attribute names (from oid_info) 4. attribute syntax (from schema) If a suitable formatter is not found the value will be rendered as bytes. Please note that the strings returned are unicode. This should work even in Python 2 where unicode must be encoded with 'utf-8' (standard LDAP encoding) . You can also have complex object istances returned in checked_attributes. c) The extend.standard.paged_search() operation is a convenient wrapper for the simple paged search as specified in the RFC2696. You can indicate how many entries will be read in the paged_size parameter (defaults to 100) and you get back a *generator* for the entries. If you set to False the generator parameter of the search will be fully executed before returning the results. If generator is set to True (the default) any subsequent search will be executed only when you read all the previous read entries, saving memory. The complete changelog for 0.9.5 is: * 0.9.5 2014.07.22 - added support for IPv6 (thanks Robert) - auto_bind can be used even for establishing tls, possible values (defined in ldap3) are: AUTO_BIND_NONE, AUTO_BIND_NO_TLS, AUTO_BIND_TLS_AFTER_BIND, AUTO_BIND_TLS_BEFORE_BIND - refactored extend package to use classes - new extended operation: get_universal_password (Novell) - new extended operation: set_universal_password (Novell) - added parsing of hostname in scheme://hostname:hostport format. This has the precedence on the parameters (thanks Sorin) - added extra checks when the schema is read (with the get_info parameter) but nothing is returned by the server - updated setuptools to version 5.4.1 - when check_name is True and schema is read attributes are checked and formatted in "checked_attributes" as specified by RFCs and schema - added formatter for generalizedTime syntax as specified in rfc 4517 (asn.1) - custom formatter can be added in Server definition Have fun, Giovanni From python3ldap at gmail.com Sun Aug 3 02:53:27 2014 From: python3ldap at gmail.com (python3ldap) Date: Sun, 3 Aug 2014 02:53:27 +0200 Subject: [python3-ldap] python3-ldap 0.9.5.1 is released Message-ID: Hello everybody, I've released the 0.9.5.1 version of python3-ldap. This is the changelog: * 0.9.5.1 2014.08.02 - getaddrinfo called only once - real_server machinery removed - messageId is now global and monotonic for the whole library - attributes are returned formatted if schema is read and check_names = True, removed checked_attributes - bind result is populated again when successful (was removed in 0.9.2.1) - exception is now raised if you receive multiple extended response to a single extended request. This is not allowed by RFC 4511 There is a big change from 0.9.5, the "checked_attributes" key of search result entry is gone. Now if the schema is read (with get_info = GET_SCHEMA or get_info = GET_ALL_INFO) and the checked_names parameter is set to True (default) the attributes values are formatted as specified in the schema and are returned in the "attributes" key of the search result entry, Single value attributes are returned directly, and not a list of a single element. If you use Python 2 you should get the attributes properly encoded as unicode string. This could lead to some compatibility problems with your code, if you already read the schema, because now attributes defined as single value are no longer a list of one element. To mantain compatibility with the previous version set the checked_names parameter to False. I've also removed the code that kept track of each messageId counter for each "real" server because this doesn't fit well with ipv6. Now there is a single message counter (for internal messageId tagging). This means that in case you have concurrent multiple server connections the server will not receive a sequential messageId counter, but there will be "gaps" in the messageId. This should not be an issue because this is allowed by RFC4511. Anyway let me know if you have troubles with message numbering. Bye, Giovanni From python3ldap at gmail.com Sun Aug 10 00:23:25 2014 From: python3ldap at gmail.com (python3ldap) Date: Sun, 10 Aug 2014 00:23:25 +0200 Subject: [python3-ldap] Library name change? Message-ID: Hello everybody, I've been asked to change the name of the library from python3-ldap to python-ldap3. This makes sense because the library is still agnostic about the Python interpreter and is strictly following version 3 of the LDAP protocol. What do you think about this? Bye, Giovanni -------------- next part -------------- An HTML attachment was scrubbed... URL: From abhay.mannur at charlotterusse.com Mon Aug 11 21:33:07 2014 From: abhay.mannur at charlotterusse.com (Abhay Mannur) Date: Mon, 11 Aug 2014 19:33:07 +0000 Subject: [python3-ldap] < Urgent Help Needed > Message-ID: Hi All, I have successfully installed following : Pip freeze output : Django==1.6.5 cx-Oracle==5.1.3 django-auth-ldap==1.2.0 ( I think I don't need this - Please confirm ) pyasn1==0.1.7 python3-ldap==0.9.5 >From Python shell I do following in the sequence : from ldap3 import Server, Connection, AUTH_SIMPLE, STRATEGY_SYNC, STRATEGY_ASYNC_THREADED, SEARCH_SCOPE_WHOLE_SUBTREE, GET_ALL_INFO s = Server('Our LDAP server', port = 636, use_ssl = True, get_info = GET_ALL_INFO) c = Connection(s, auto_bind = True, client_strategy = STRATEGY_SYNC, user=, password=, authentication=AUTH_SIMPLE, check_names=True) Connection fails with invalid credentials error but after I execute connection command, I get s.info showing me all server details. My windows/network admin tells me following : It does look like you're are connecting to the LDAP server and querying basic information. Typically I look for a couple things in a configuration file to make sure it binds properly (authenticated). * Server name - OK * Port o 636 (SSL) o I see you have this already * Base DN o DC=CRUSSE,DC=local o Even though it's querying the default naming context, typically you have to specify this information in your configuration file or connection string. * Username Attribute o sAMAccountName o Because LDAP isn't always Active Directory you typically have to specify what the attribute is for the username. * Bind User DN o CN=Abhay Mannur,OU=Users,OU=IT,OU=San Francisco,OU=Sites,OU=Charlotte Russe,DC=CRUSSE,DC=local o Typically we enter in a service account here, but you can use your credentials for now. * Bind User Password o ******** o Your AD password It looks like you may be missing the username attribute and/or not entering in the full bind DN. Again, the bind User DN would typically be a service account. Is there a configuration file anywhere or is everything just getting specified as a parameter when connecting? I'm totally lost with as doing LDAP authentication for the first time. Please help me with this configuration and/or my connection object parameters etc. Thanks, Abhay Mannur Programmer Analyst III abhay.mannur at charlotterusse.com Office : 415-820-6541 Cell : 415-279-9565 [cid:image001.jpg at 01CEC9C0.04FD8370] -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.jpg Type: image/jpeg Size: 2509 bytes Desc: image001.jpg URL: From jcasale at activenetwerx.com Sat Aug 16 22:51:31 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Sat, 16 Aug 2014 20:51:31 +0000 Subject: [python3-ldap] Library name change? In-Reply-To: References: Message-ID: <42d475e72b1f4bf38bc3b6007f522171@exch.activenetwerx.com> > Hello everybody, > I've been asked to change the name of the library from python3-ldap to python-ldap3. > This makes sense because the library is still?agnostic about the Python interpreter and > is strictly following version 3 of the LDAP?protocol.? > > What do you think about this? Hi Giovanni, I have this library littered all over the place in work I have done. I can test my style of invocation and usage and assert with a high degree of confidence what impact that an upgrade may have. A name change will be a serious thorn causing individual testing across a potentially large set of code. I question just how necessary a change like this and what genuine result will be achieved by it. jlc From python.org at veggiechinese.net Sun Aug 17 01:04:24 2014 From: python.org at veggiechinese.net (Will Yardley) Date: Sat, 16 Aug 2014 16:04:24 -0700 Subject: [python3-ldap] Library name change? In-Reply-To: References: Message-ID: <20140816230424.GA23566@aura.veggiechinese.net> On Sun, Aug 10, 2014 at 12:23:25AM +0200, python3ldap wrote: > I've been asked to change the name of the library from python3-ldap to > python-ldap3. This makes sense because the library is still agnostic about > the Python interpreter and is strictly following version 3 of the > LDAP protocol. I have always thought the name doesn't sound right as-is, especially since it has Python 2 compatibility. I think python-ldap3 makes a lot more sense (though tying it into the version of the LDAP protocol, rather than into the iteration of the python-ldap library, e.g., python-ldap2) potentially does make the name obsolete if there's ever a new version of the LDAP protool (possibly unlikely at this point, I guess). A few thoughts, though: 1) I'm wondering if it's possible to make the library use native Python 3 libraries when available in the case where you've had to re-create Python 3 functionality for compatibility with 2, and defining the things that do need to be back-ported in as central a way as possible. 2) Given the complaint mentioned by another poster on this topic, is there a way to make the module allow the old name to continue to work for backwards compatibility? w From python3ldap at gmail.com Sun Aug 17 12:14:26 2014 From: python3ldap at gmail.com (Python3-ldap) Date: Sun, 17 Aug 2014 12:14:26 +0200 Subject: [python3-ldap] R: Library name change? In-Reply-To: <42d475e72b1f4bf38bc3b6007f522171@exch.activenetwerx.com> References: <42d475e72b1f4bf38bc3b6007f522171@exch.activenetwerx.com> Message-ID: <53f08091.2678c20a.0149.ffffed73@mx.google.com> Hi Joseph, Why do you say that the name change would impact the code? The name space would remain the same (ldap3) so the code should not change, it's just the name of the package that would be different. This should impact the installation script or the requirements.txt. What is your invocation pattern for the library? I'm asking this to understand the impact of this hypothetical change. Thanks, Giovanni ----- Messaggio originale ----- Da: "Joseph L. Casale" Inviato: ?16/?08/?2014 22:52 A: "python3-ldap at python.org" Oggetto: Re: [python3-ldap] Library name change? > Hello everybody, > I've been asked to change the name of the library from python3-ldap to python-ldap3. > This makes sense because the library is still?agnostic about the Python interpreter and > is strictly following version 3 of the LDAP?protocol.? > > What do you think about this? Hi Giovanni, I have this library littered all over the place in work I have done. I can test my style of invocation and usage and assert with a high degree of confidence what impact that an upgrade may have. A name change will be a serious thorn causing individual testing across a potentially large set of code. I question just how necessary a change like this and what genuine result will be achieved by it. jlc _______________________________________________ python3-ldap mailing list python3-ldap at python.org https://mail.python.org/mailman/listinfo/python3-ldap -------------- next part -------------- An HTML attachment was scrubbed... URL: From python3ldap at gmail.com Sun Aug 17 13:46:07 2014 From: python3ldap at gmail.com (Python3-ldap) Date: Sun, 17 Aug 2014 13:46:07 +0200 Subject: [python3-ldap] R: Library name change? In-Reply-To: <20140816230424.GA23566@aura.veggiechinese.net> References: <20140816230424.GA23566@aura.veggiechinese.net> Message-ID: <53f0960f.88afc20a.75f7.fffff3f4@mx.google.com> Hello Will, when I started to develop python3-ldap I was focused on filling the gap for ldap in python3, so I named the library thinking it would be a python 3 only package. At first stage of development I saw it was quite easy to write code that worked either in python 3 and python 2, so I started to test against both version (actually 2.6, 2.7 and 3.x). I was surprised to find that people started using python3-ldap in python 2 too, despite the presence of the python-ldap package (with a completely different API). So the name change could reflect that. There is really a little portion of code specific to python 3 in the library and it requires python 3.4 to take advantage of the new SSLContext class of the SSL package. So regarding your two questions I can say that (1) there is no python 3 "core" on the library, there are just a few 'if str == bytes:' statements to check if string is unicode or not (and a few backported functions regarding SSL) and that (2) the obvious way to maintain compatibility is to release two packages with different names (python3-ldap and python-ldap3) and the same content, but I don't think this is an acceptable solution Another less obvious way could be to make python3-ldap a "wrapper" to python-ldap3, this could leave space for an hypothetical python2-ldap that could be released when major differences arise. Bye, Giovanni ----- Messaggio originale ----- Da: "Will Yardley" Inviato: ?17/?08/?2014 01:13 A: "python3-ldap at python.org" Oggetto: Re: [python3-ldap] Library name change? On Sun, Aug 10, 2014 at 12:23:25AM +0200, python3ldap wrote: > I've been asked to change the name of the library from python3-ldap to > python-ldap3. This makes sense because the library is still agnostic about > the Python interpreter and is strictly following version 3 of the > LDAP protocol. I have always thought the name doesn't sound right as-is, especially since it has Python 2 compatibility. I think python-ldap3 makes a lot more sense (though tying it into the version of the LDAP protocol, rather than into the iteration of the python-ldap library, e.g., python-ldap2) potentially does make the name obsolete if there's ever a new version of the LDAP protool (possibly unlikely at this point, I guess). A few thoughts, though: 1) I'm wondering if it's possible to make the library use native Python 3 libraries when available in the case where you've had to re-create Python 3 functionality for compatibility with 2, and defining the things that do need to be back-ported in as central a way as possible. 2) Given the complaint mentioned by another poster on this topic, is there a way to make the module allow the old name to continue to work for backwards compatibility? w _______________________________________________ python3-ldap mailing list python3-ldap at python.org https://mail.python.org/mailman/listinfo/python3-ldap -------------- next part -------------- An HTML attachment was scrubbed... URL: From mr.gary.waters at gmail.com Mon Aug 18 06:01:36 2014 From: mr.gary.waters at gmail.com (Gary Waters) Date: Sun, 17 Aug 2014 21:01:36 -0700 Subject: [python3-ldap] Library name change? In-Reply-To: <20140816230424.GA23566@aura.veggiechinese.net> References: <20140816230424.GA23566@aura.veggiechinese.net> Message-ID: <53F17AA0.8090804@gmail.com> Why not just do an "import as" ? For example: import NEW_MODULE_NAME as OLD_MODULE_NAME or import PYTHON_LDAP3 as LDAP3-PYTHON So you can continue to use methods with the old name. This would allow the name to evolve to something that is more logical, and have little impact to previously written scripts. Hope this helps, Gary On 08/16/2014 04:04 PM, Will Yardley wrote: > On Sun, Aug 10, 2014 at 12:23:25AM +0200, python3ldap wrote: > >> I've been asked to change the name of the library from python3-ldap to >> python-ldap3. This makes sense because the library is still agnostic about >> the Python interpreter and is strictly following version 3 of the >> LDAP protocol. > > I have always thought the name doesn't sound right as-is, especially > since it has Python 2 compatibility. I think python-ldap3 makes a lot > more sense (though tying it into the version of the LDAP protocol, > rather than into the iteration of the python-ldap library, e.g., > python-ldap2) potentially does make the name obsolete if there's ever a > new version of the LDAP protool (possibly unlikely at this point, I > guess). > > A few thoughts, though: > 1) I'm wondering if it's possible to make the library use native Python 3 > libraries when available in the case where you've had to re-create > Python 3 functionality for compatibility with 2, and defining the things > that do need to be back-ported in as central a way as possible. > > 2) Given the complaint mentioned by another poster on this topic, is > there a way to make the module allow the old name to continue to work > for backwards compatibility? > > w > > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap > From jcasale at activenetwerx.com Mon Aug 18 12:11:58 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Mon, 18 Aug 2014 10:11:58 +0000 Subject: [python3-ldap] Library name change? In-Reply-To: <53f08091.2678c20a.0149.ffffed73@mx.google.com> References: <42d475e72b1f4bf38bc3b6007f522171@exch.activenetwerx.com> <53f08091.2678c20a.0149.ffffed73@mx.google.com> Message-ID: <553e503ff0cf4199b3a4654dc1dee23d@exch.activenetwerx.com> > Hi Joseph, > Why do you say that the name change would impact the code? The name space would > remain the same (ldap3) so the code should not change, it's just the name of the package > that would be different. This should impact the installation script or the requirements.txt. >What is your invocation pattern for the library? > > I'm asking this to understand the impact of this hypothetical change. Hi Giovanni, Ok, good to know, I erroneously assumed the module would change as well. In that case I am indifferent... Thanks! jlc From okelet at gmail.com Wed Aug 20 14:44:50 2014 From: okelet at gmail.com (=?UTF-8?Q?Juan_Asensio_S=C3=A1nchez?=) Date: Wed, 20 Aug 2014 14:44:50 +0200 Subject: [python3-ldap] Check modify operation result Message-ID: I have read the docs but I haven't found the return types of the connection methods (add, modify, search, ...). For the search method, I know I hace the result and response variables in the connection class, but is it the same for the modify operation? Does the modify operation fill also the response (with what?), or just the result? If the modify fails, does it throw an exception or just fills an error in the result variable? Regards and thnaks by this great lib. -------------- next part -------------- An HTML attachment was scrubbed... URL: From python3ldap at gmail.com Mon Aug 25 22:54:06 2014 From: python3ldap at gmail.com (python3ldap) Date: Mon, 25 Aug 2014 22:54:06 +0200 Subject: [python3-ldap] python3-ldap 0.9.5.3 is released Message-ID: Hello everybody, I've released the 0.9.5.3 version of python3-ldap.Now attributes returned in search are searchable in a case insensitive way by default. This is probably helpful at interactive prompt because you can read the value of attributes without specify the exact case of the key. FOr example you can access c,response[0]['attributes']['postalAddress'] or c,response[0]['attributes']['postaladdress'] and get the same values back. There is a simple class in the ldap3.utils.caseInsensitiveDictionary package that contains CaseInsensitiveDict, a class that subclasses the collections.abc.MutableMappings and can be used as a usaul dictionary. You use it if you need and it perform also equality between two CaseInsensitiveDicts or a CaseInsensitiveDict and a dict, in the latter case the case is ignored even in the dict. In 0.9.5.3 there is a fix to properly read the schema for Active Directory and 389 Directory Server, where the schema attributes must be explicitly requested. There are also a few extended operations for eDirectory and a utility function to convert a dn to a list of name components. Thiese are the changelogs for 0.9.5.3 and 0.9.5.2: * 0.9.5.3 2014.08.24 - elements returned in schema and dsa info are in a case insensitive dictionary (can be changed in ldap3.CASE_INSENSITIVE_SCHEMA_NAMES = True|False) - attributes name returned in searches are now case insensitive (can be changed in ldap3.CASE_INSENSITIVE_ATTRIBUTE_NAMES = True|False) - change parameter name from separe_rdn to separate_rnd in ldap3.utils.conv.to_dn() - sync dev from Bitbucket to GitHub - schema attributes are explicitly read (useful for Active directory and 389 Directory Server) - new extended operation: list_replicas (Novell) - new extended operation: get_replica_info (Novell) - new extended operation: partition_entry_count (Novell) - renamed convert_to_ldif() to _convert_to_ldif() * 0.9.5.2 2014.08.05 - fixed LDAPOperationResult.__str__ (thanks David) - added to_dn() in utils.conv to convert a dn string in a list of components (strings or tuples) - added __version__ in ldap3 - don't raise exception if the schema cannot be read in unauthenticated state - server.address_info is now a property Have fun, Giovanni From flo at chaoflow.net Mon Sep 22 19:15:45 2014 From: flo at chaoflow.net (Florian Friesdorf) Date: Mon, 22 Sep 2014 19:15:45 +0200 Subject: [python3-ldap] Feedback on aspects of python3-ldap's API References: <541e87f215b5c_3e783fe671e166fc2407244@discourse.mail> Message-ID: <87a95r8tku.fsf@eve.Speedport_W_921V_1_35_000> Hi Giovanni, On community.plone.org[1] you are asking what we consider confusing about python3-ldap's API. I hope it is in your interest that I post this feedback here to the python3-ldap list. To the other aspects of your posting I will reply on community.plone.org [1] https://community.plone.org/t/ldap-status-quo-and-where-to-go-from-here/285 On Sun, Sep 21 2014, cannata_g wrote: > Hello everybody, > I'm the author of python3-ldap. I read in your message that you think > that the python3-ldap API is "confusing". I'd like to know what you > mean by that, are you referring to the documentation (still not > completed) or to the API itself?. The opinion that python3-ldap's API is confusing to us, was formed after a brief look at the quick tour[2]: [2] http://pythonhosted.org/python3-ldap/quicktour.html To perform a search, python3-ldap uses a connection object on which a search method is called with the search parameters. The result is not returned but instead there are .result and .response attributes on the connection. When using a connection as context-manager, the connection lives on after leaving the context. Within the context the binding to the ldap server is magically changed. Both these things we consider rather untypical for pythonic APIs. regards Marko and Florian -- Florian Friesdorf GPG FPR: 7A13 5EEE 1421 9FC2 108D BAAF 38F8 99A3 0C45 F083 Jabber/XMPP: flo at chaoflow.net IRC: chaoflow on freenode,ircnet,blafasel,OFTC -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 835 bytes Desc: not available URL: From python3ldap at gmail.com Tue Sep 23 08:55:21 2014 From: python3ldap at gmail.com (python3ldap) Date: Tue, 23 Sep 2014 08:55:21 +0200 Subject: [python3-ldap] Feedback on aspects of python3-ldap's API In-Reply-To: <87a95r8tku.fsf@eve.Speedport_W_921V_1_35_000> References: <541e87f215b5c_3e783fe671e166fc2407244@discourse.mail> <87a95r8tku.fsf@eve.Speedport_W_921V_1_35_000> Message-ID: Hi Florian, thanks for your message. I've crafted the API upon the official latest LDAP specification (RFC 4510 and other). Each LDAP operation returns a result code and an optional "payload". The "search" operation is not different from the other operations, so when you invoke it you get back a boolean that specify if the operation itself (regarding to the protocol) was succesful. The result and the "payload" are too information-rich to be returned as a simple value (or tuple). So I give them back as dictionaries (after decoding and formatting as required by the protocol) in the connection.result and connection.response attributes.With this approach you can have the complete control on what the LDAP server is returning (referral handling is a good example of where this approach is helpful) and can easily investigate any problem you could have. Furthermore having decoupled the result and payload from the operation is helpful because you can "plug" different "connection strategies" and they work all the same. For example you can have the "reusable" strategy (a multiple connection strategy to multiple servers) and keep the code almost equal to the synchronous strategy. Even with asynchronous strategies you get back the same result and response dictionaries with a inquiry method of the connection itself. Anyway there are some convenience functions in the ldap3.extend.standard namespace that act as you intend. In the case of "paged" searches you can get the result back directly in the search operation that act as a generator (or an accumulator). For example you can have: # simple paged search with generator - useful when returning a big dataset for response in self.connection.extend.standard.paged_search('o=test', '(cn=*)'): do_whatever_with(response) or: # simple paged search with accumulator - the paged search is executed and accumulated in the result responses = self.connection.extend.standard.paged_search('o=test', '(cn=*)', generator=False) Regarding the connection context manager there is no magic at all in it. As stated in the docs the connection retains the status it had before entering the context. This has been done because it's quite expensive to bind a connection each time you get in the context, so the connection is not destroyed when exiting it. Furthermore if you use "lazy" connections (that bind only if there is some real operation to perform) you gain a speed boost in long standing routines (I work mainly on identity management systems and this has proven useful). Feel free to give back suggestion and criticism on this mailing list. Bye, Giovanni 2014-09-22 19:15 GMT+02:00 Florian Friesdorf : > > Hi Giovanni, > > On community.plone.org[1] you are asking what we consider confusing > about python3-ldap's API. I hope it is in your interest that I post this > feedback here to the python3-ldap list. To the other aspects of your > posting I will reply on community.plone.org > > [1] https://community.plone.org/t/ldap-status-quo-and-where-to-go-from-here/285 > > On Sun, Sep 21 2014, cannata_g wrote: >> Hello everybody, >> I'm the author of python3-ldap. I read in your message that you think >> that the python3-ldap API is "confusing". I'd like to know what you >> mean by that, are you referring to the documentation (still not >> completed) or to the API itself?. > > The opinion that python3-ldap's API is confusing to us, was formed after > a brief look at the quick tour[2]: > > [2] http://pythonhosted.org/python3-ldap/quicktour.html > > To perform a search, python3-ldap uses a connection object on which a > search method is called with the search parameters. The result is not > returned but instead there are .result and .response attributes on the > connection. > > When using a connection as context-manager, the connection lives on > after leaving the context. Within the context the binding to the ldap > server is magically changed. > > Both these things we consider rather untypical for pythonic APIs. > > regards > Marko and Florian > -- > Florian Friesdorf > GPG FPR: 7A13 5EEE 1421 9FC2 108D BAAF 38F8 99A3 0C45 F083 > Jabber/XMPP: flo at chaoflow.net > IRC: chaoflow on freenode,ircnet,blafasel,OFTC > > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap > From flo at chaoflow.net Tue Sep 23 12:31:55 2014 From: flo at chaoflow.net (Florian Friesdorf) Date: Tue, 23 Sep 2014 12:31:55 +0200 Subject: [python3-ldap] Feedback on aspects of python3-ldap's API In-Reply-To: References: <541e87f215b5c_3e783fe671e166fc2407244@discourse.mail> <87a95r8tku.fsf@eve.Speedport_W_921V_1_35_000> Message-ID: <87wq8u7hlw.fsf@eve.Speedport_W_921V_1_35_000> Hi Giovanni, On Tue, Sep 23 2014, python3ldap wrote: > Regarding the connection context manager there is no magic at all in > it. As stated in the docs the connection retains the status it had > before entering the context. This has been done because it's quite > expensive to bind a connection each time you get in the context, so > the connection is not destroyed when exiting it. Furthermore if you > use "lazy" connections (that bind only if there is some real operation > to perform) you gain a speed boost in long standing routines (I work > mainly on identity management systems and this has proven useful). with Connection(...) as c: ... I would expect the connection to be closed when the context is left, compare to: with open('file') as f: ... To change the state of binding as part of a context manager I would expect something like: c = Connection(...) # unbound with c.bind(...): ... best regards florian > 2014-09-22 19:15 GMT+02:00 Florian Friesdorf : >> >> Hi Giovanni, >> >> On community.plone.org[1] you are asking what we consider confusing >> about python3-ldap's API. I hope it is in your interest that I post this >> feedback here to the python3-ldap list. To the other aspects of your >> posting I will reply on community.plone.org >> >> [1] https://community.plone.org/t/ldap-status-quo-and-where-to-go-from-here/285 >> >> On Sun, Sep 21 2014, cannata_g wrote: >>> Hello everybody, >>> I'm the author of python3-ldap. I read in your message that you think >>> that the python3-ldap API is "confusing". I'd like to know what you >>> mean by that, are you referring to the documentation (still not >>> completed) or to the API itself?. >> >> The opinion that python3-ldap's API is confusing to us, was formed after >> a brief look at the quick tour[2]: >> >> [2] http://pythonhosted.org/python3-ldap/quicktour.html >> >> To perform a search, python3-ldap uses a connection object on which a >> search method is called with the search parameters. The result is not >> returned but instead there are .result and .response attributes on the >> connection. >> >> When using a connection as context-manager, the connection lives on >> after leaving the context. Within the context the binding to the ldap >> server is magically changed. >> >> Both these things we consider rather untypical for pythonic APIs. >> >> regards >> Marko and Florian >> -- >> Florian Friesdorf >> GPG FPR: 7A13 5EEE 1421 9FC2 108D BAAF 38F8 99A3 0C45 F083 >> Jabber/XMPP: flo at chaoflow.net >> IRC: chaoflow on freenode,ircnet,blafasel,OFTC >> >> _______________________________________________ >> python3-ldap mailing list >> python3-ldap at python.org >> https://mail.python.org/mailman/listinfo/python3-ldap >> -- Florian Friesdorf GPG FPR: 7A13 5EEE 1421 9FC2 108D BAAF 38F8 99A3 0C45 F083 Jabber/XMPP: flo at chaoflow.net IRC: chaoflow on freenode,ircnet,blafasel,OFTC -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 835 bytes Desc: not available URL: From python3ldap at gmail.com Tue Sep 23 19:33:52 2014 From: python3ldap at gmail.com (python3ldap) Date: Tue, 23 Sep 2014 19:33:52 +0200 Subject: [python3-ldap] python3-ldap 0.9.5.4 released Message-ID: Hello, I've released version 0.9.5.4 of python3-ldap. The main feature is the parsing of DNs and referral URIs. You can find 2 functions for DN parsing (follow the specifications in RFC 4514). with parse_dn(dn) you get an exception if the dn is not valid and get back a list of tuple with the dn components, while with safe_dn(dn) you get back a string with dn safely escaped (if possible). The changelog is: - Fixed security issue in lazy connections (thanks Moritz) - Added ldap3.utils.dn with parse_dn(dn) to verify dn compliance with RFC4514 - Added safe_dn(dn) to properly escape dn (if possible) - Added ldap3.utils.uri with parse_uri(uri) to verify uri compliance with RFC4516 - Check for trailing slashes in hostname (thanks Dylan) - Timeout for socket connect operation. Server.connect_timeout = seconds_to_wait_for_establishing_connection (thanks Florian) - Closing socket error doesn't raise exception anymore - ServerPool can be implicity defined with a list of server names (even when defining a connection) This is my roadmap to version 1.0: - 1. Safe parsing of DN (done in 0.9.5.4) - 2. Active directory specific operations - 3. Offline standard schema definition (to allow clients to be aware of the standard RFC defined schema even if the server is not returning it) - 4. Custom offline schema definition (to add custom types to offline schema - 5. Mocking strategy (for testing purpose) - 6 GSSAPI SASL authentication - 7 Multiserver testing lab - 8 Updated docs and tutorials Do you think that something is still missing? Bye, Giovanni From python.org at veggiechinese.net Tue Sep 23 20:12:18 2014 From: python.org at veggiechinese.net (Will Yardley) Date: Tue, 23 Sep 2014 11:12:18 -0700 Subject: [python3-ldap] python3-ldap 0.9.5.4 released In-Reply-To: References: Message-ID: <20140923181218.GO8353@aura.veggiechinese.net> On Tue, Sep 23, 2014 at 07:33:52PM +0200, python3ldap wrote: > Do you think that something is still missing? I wonder if there's a terser or easier to read way of doing this: from ldap3 import [...] SEARCH_SCOPE_WHOLE_SUBTREE c.search('o=test','(objectClass=*)', SEARCH_SCOPE_WHOLE_SUBTREE, [...] At the least, the long constant, while precise, takes up an awful lot of real estate. I'm not sure what the cleanest / most proper / most "pythonic" way would be, but I would have thought just having a parameter specified like 'scope=subtree' or something (with a default that represents the most common use-case) would be simpler and much easier to read, unless this way of doing things is deprecated for some reason. w From python3ldap at gmail.com Tue Sep 23 22:52:16 2014 From: python3ldap at gmail.com (python3ldap) Date: Tue, 23 Sep 2014 22:52:16 +0200 Subject: [python3-ldap] python3-ldap 0.9.5.4 released In-Reply-To: <20140923181218.GO8353@aura.veggiechinese.net> References: <20140923181218.GO8353@aura.veggiechinese.net> Message-ID: Hi Will, you're right, I chose those configuration parameter at the very beginning of the project, when I started reading the different RFCs. So they made sense because I could refer to the relevant part of the RFC, and it was not clear to me what and how many parameters I needed. I will make them simpler in a next release, maintaining compatability with the older for a while. Thanks for the suggestion. Bye, Giovanni 2014-09-23 20:12 GMT+02:00 Will Yardley : > On Tue, Sep 23, 2014 at 07:33:52PM +0200, python3ldap wrote: > >> Do you think that something is still missing? > > I wonder if there's a terser or easier to read way of doing this: > > from ldap3 import [...] SEARCH_SCOPE_WHOLE_SUBTREE > c.search('o=test','(objectClass=*)', SEARCH_SCOPE_WHOLE_SUBTREE, [...] > > At the least, the long constant, while precise, takes up an awful lot of > real estate. > > I'm not sure what the cleanest / most proper / most "pythonic" way would > be, but I would have thought just having a parameter specified like > 'scope=subtree' or something (with a default that represents the most > common use-case) would be simpler and much easier to read, unless this > way of doing things is deprecated for some reason. > > w > > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap From python.org at veggiechinese.net Tue Sep 23 23:09:38 2014 From: python.org at veggiechinese.net (Will Yardley) Date: Tue, 23 Sep 2014 14:09:38 -0700 Subject: [python3-ldap] Feedback on aspects of python3-ldap's API In-Reply-To: References: <541e87f215b5c_3e783fe671e166fc2407244@discourse.mail> <87a95r8tku.fsf@eve.Speedport_W_921V_1_35_000> Message-ID: <20140923210938.GQ8353@aura.veggiechinese.net> > Anyway there are some convenience functions in the > ldap3.extend.standard namespace that act as you intend. In the case of > "paged" searches you can get the result back directly in the search > operation that act as a generator (or an accumulator). For example you > can have: > > # simple paged search with generator - useful when returning a big dataset > for response in self.connection.extend.standard.paged_search('o=test', > '(cn=*)'): > do_whatever_with(response) This seems much easier than, and preferable to, the first example in your documentation, which looks similar to the example for dealing with paged results in python-ldap. However, given how common search result limits are with the default configs of modern LDAP implementations, both AD and other systems like 389, I wonder if it wouldn't be easier (from the standpoint of end-users) to just have an option to the connection and / or the query that lets you set the # of max results per query, i.e.,, why not just let the user specify 'paged_size=1000' and let the code handle how to deal with that in a less exposed way. If it's set for the connection, the limit would apply to all searches, and if it's set for the search, it would apply to that search. That way, instead of having to call, e.g., connection.extend.standard.paged_search('o=test', '(cn=*)', paged_size=1000) you can just call search('o=test', '(cn=*)', paged_size=1000) and then have the results presented in a data structure in the same way an unpaged search would be. I do think that feedback from people with more distance from the module, both ordinary users and developers of other modules, might be handy. While python-ldap has a lot of flaws IMHO, and I've long been surprised at some of the things it can't do natively, if something's going to replace it, I'd love to see it be something that is easy to use as well as powerful -- the ease of use and consistency of modules is one of the things that I think makes Python strong. And, while there might be some pain in changing interfaces or maintaining backwards compatibility now, it's nothing compared to what it will be once the project is more widely used. To me, imaplib and smtplib (while they do somewhat different types of things) are great examples of modules that are powerful, flexible, but also very easy to use for simple use-cases, and have a very logical interface. Someone with fairly little understanding of the protocol can configure them to receive / send mail with just a few configuration options (see, https://docs.python.org/2/library/imaplib.html#imap4-example). But in cases where you need to directly access a particular method to, for example, start a session and send RCPT TO, without actually sending a message, it's also very easy to deal with. And, as I've mentioned before, I think figuring out some more abstract way to represent search filters would be really great, though I will admit to not knowing exactly how such a layer would look. I don't find the current one very logical personally, and from what I understand, there are a few types of combinations that can't be represented using it. w From jcasale at activenetwerx.com Wed Sep 24 00:23:15 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Tue, 23 Sep 2014 22:23:15 +0000 Subject: [python3-ldap] python3-ldap 0.9.5.4 released In-Reply-To: <20140923181218.GO8353@aura.veggiechinese.net> References: , <20140923181218.GO8353@aura.veggiechinese.net> Message-ID: <1411510995540.3070@activenetwerx.com> > I wonder if there's a terser or easier to read way of doing this: > > from ldap3 import [...] SEARCH_SCOPE_WHOLE_SUBTREE > c.search('o=test','(objectClass=*)', SEARCH_SCOPE_WHOLE_SUBTREE, [...] You can't format your code differently? c.search( 'o=test', '(objectClass=*)', SEARCH_SCOPE_WHOLE_SUBTREE, [...] ) Frankly, this is far more readable, makes more sense in a diff and just plain looks better. jlc From python.org at veggiechinese.net Wed Sep 24 00:44:39 2014 From: python.org at veggiechinese.net (Will Yardley) Date: Tue, 23 Sep 2014 15:44:39 -0700 Subject: [python3-ldap] python3-ldap 0.9.5.4 released In-Reply-To: <1411510995540.3070@activenetwerx.com> References: <20140923181218.GO8353@aura.veggiechinese.net> <1411510995540.3070@activenetwerx.com> Message-ID: <20140923224439.GR8353@aura.veggiechinese.net> On Tue, Sep 23, 2014 at 10:23:15PM +0000, Joseph L. Casale wrote: > > I wonder if there's a terser or easier to read way of doing this: > > > > from ldap3 import [...] SEARCH_SCOPE_WHOLE_SUBTREE > > c.search('o=test','(objectClass=*)', SEARCH_SCOPE_WHOLE_SUBTREE, [...] > > You can't format your code differently? > > c.search( > 'o=test', > '(objectClass=*)', > SEARCH_SCOPE_WHOLE_SUBTREE, > [...] > ) > > Frankly, this is far more readable, makes more sense in a diff and just plain looks > better. Sure, I was just paraphrasing the example. I can (and would) format the code differently. But, I still personally find: scope=foo simpler and easier to read / understand. I know there are plusses and minuses of doing import ldap3 vs. from ldap3 import [....] as used in the example. but having to import various constants there also becomes unwieldy quickly. w From jcasale at activenetwerx.com Wed Sep 24 00:59:32 2014 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Tue, 23 Sep 2014 22:59:32 +0000 Subject: [python3-ldap] python3-ldap 0.9.5.4 released In-Reply-To: <20140923224439.GR8353@aura.veggiechinese.net> References: <20140923181218.GO8353@aura.veggiechinese.net> <1411510995540.3070@activenetwerx.com>, <20140923224439.GR8353@aura.veggiechinese.net> Message-ID: <1411513172401.92056@activenetwerx.com> > I know there are plusses and minuses of doing > import ldap3 > vs. > from ldap3 import [....] > as used in the example. I always use the later, I only import what I use and never import the entire module unless it makes sense, ie its needed for isolation. > but having to import various constants there also becomes unwieldy > quickly. Well, thats a matter of opinion, I find the following short, terse and specific: from ldap3 import ( Connection, Server, ServerPool, POOLING_STRATEGY_ROUND_ROBIN, SEARCH_SCOPE_BASE_OBJECT, SEARCH_SCOPE_WHOLE_SUBTREE, STRATEGY_SYNC_RESTARTABLE ) When you have more than one constant, coming up with creative acronyms to introduce unnecessary obfuscation as they all begin collide serves no useful purpose. I actually am relieved to see the full name, especially in the case of this library were everything closely relates to the spec so when I am looking something up in the rfc's for example, I done have to convert (rfc) LONG_KEY_WORD to (acronym) LKWZZ because A through ZY are already used. Think of other people who must maintain your code:) When I see code with anti patterns like 'import someModule as sm' I sigh... Now as I am reading through it I need to stop and think, or worse go and check to see what the heck "sm" is. So if isolation is needed, ldap3.Connection leaves nothing to be guessed whereas if I know I am not in a scenario requiring isolation, Connection is just as obvious. There is no tax on real estate, nor points for conserving it. You can still maintain the silly 79 char limit from pep8 with proper formatting as illustrated. jlc From python3ldap at gmail.com Wed Sep 24 09:40:02 2014 From: python3ldap at gmail.com (python3ldap) Date: Wed, 24 Sep 2014 09:40:02 +0200 Subject: [python3-ldap] Feedback on aspects of python3-ldap's API In-Reply-To: <87wq8u7hlw.fsf@eve.Speedport_W_921V_1_35_000> References: <541e87f215b5c_3e783fe671e166fc2407244@discourse.mail> <87a95r8tku.fsf@eve.Speedport_W_921V_1_35_000> <87wq8u7hlw.fsf@eve.Speedport_W_921V_1_35_000> Message-ID: Hello Florian, the connection context works as you state: >>> with Connection('server', 'admin', 'password') as c: ... c.search('o=test', '(cn=*)') ... r = c.response >>> str(c) 'ldap://server - cleartext - user: admin - unbound - closed - tls not started - not listening - SyncWaitStrategy' (so the connection is open, bound, operations are executed and then the connection is unbounded) the only difference is that if the connection was already defined it retains the same state it had before entering the context: c = Connection('server', 'admin', 'password') c.bind() with c: ... c.search('o=test', '(cn=*)') ... r = c.response >>> str(c) 'ldap://server - cleartext - user: admin - unbound - closed - tls not started - not listening - SyncWaitStrategy' I don't think that the syntax "with c.bind():" is more clear because the Connection object does exist indipendently from the bind() operation. (LDAP protocol states that you can even send operations without binding). Bye, Giovanni 2014-09-23 12:31 GMT+02:00 Florian Friesdorf : > > Hi Giovanni, > > On Tue, Sep 23 2014, python3ldap wrote: >> Regarding the connection context manager there is no magic at all in >> it. As stated in the docs the connection retains the status it had >> before entering the context. This has been done because it's quite >> expensive to bind a connection each time you get in the context, so >> the connection is not destroyed when exiting it. Furthermore if you >> use "lazy" connections (that bind only if there is some real operation >> to perform) you gain a speed boost in long standing routines (I work >> mainly on identity management systems and this has proven useful). > > with Connection(...) as c: > ... > > I would expect the connection to be closed when the context is left, > compare to: > > with open('file') as f: > ... > > To change the state of binding as part of a context manager I would > expect something like: > > c = Connection(...) # unbound > with c.bind(...): > ... > > best regards > florian > >> 2014-09-22 19:15 GMT+02:00 Florian Friesdorf : >>> >>> Hi Giovanni, >>> >>> On community.plone.org[1] you are asking what we consider confusing >>> about python3-ldap's API. I hope it is in your interest that I post this >>> feedback here to the python3-ldap list. To the other aspects of your >>> posting I will reply on community.plone.org >>> >>> [1] https://community.plone.org/t/ldap-status-quo-and-where-to-go-from-here/285 >>> >>> On Sun, Sep 21 2014, cannata_g wrote: >>>> Hello everybody, >>>> I'm the author of python3-ldap. I read in your message that you think >>>> that the python3-ldap API is "confusing". I'd like to know what you >>>> mean by that, are you referring to the documentation (still not >>>> completed) or to the API itself?. >>> >>> The opinion that python3-ldap's API is confusing to us, was formed after >>> a brief look at the quick tour[2]: >>> >>> [2] http://pythonhosted.org/python3-ldap/quicktour.html >>> >>> To perform a search, python3-ldap uses a connection object on which a >>> search method is called with the search parameters. The result is not >>> returned but instead there are .result and .response attributes on the >>> connection. >>> >>> When using a connection as context-manager, the connection lives on >>> after leaving the context. Within the context the binding to the ldap >>> server is magically changed. >>> >>> Both these things we consider rather untypical for pythonic APIs. >>> >>> regards >>> Marko and Florian >>> -- >>> Florian Friesdorf >>> GPG FPR: 7A13 5EEE 1421 9FC2 108D BAAF 38F8 99A3 0C45 F083 >>> Jabber/XMPP: flo at chaoflow.net >>> IRC: chaoflow on freenode,ircnet,blafasel,OFTC >>> >>> _______________________________________________ >>> python3-ldap mailing list >>> python3-ldap at python.org >>> https://mail.python.org/mailman/listinfo/python3-ldap >>> > > -- > Florian Friesdorf > GPG FPR: 7A13 5EEE 1421 9FC2 108D BAAF 38F8 99A3 0C45 F083 > Jabber/XMPP: flo at chaoflow.net > IRC: chaoflow on freenode,ircnet,blafasel,OFTC From python3ldap at gmail.com Wed Sep 24 10:05:03 2014 From: python3ldap at gmail.com (python3ldap) Date: Wed, 24 Sep 2014 10:05:03 +0200 Subject: [python3-ldap] Feedback on aspects of python3-ldap's API In-Reply-To: <20140923210938.GQ8353@aura.veggiechinese.net> References: <541e87f215b5c_3e783fe671e166fc2407244@discourse.mail> <87a95r8tku.fsf@eve.Speedport_W_921V_1_35_000> <20140923210938.GQ8353@aura.veggiechinese.net> Message-ID: Hi Will, I agree that the docs are not updated and don't reflect the latest features of the library. I'm going through a major rewriting of the manual, hope to have a better version soon. I will try to simplify the simple paged operation in the connection.search() as you suggest. Regarding the abstraction layer I've included is a module I used in a previous project. I know there are some filter combination that are cannot be express with it, but it very simple to use. It is still only a "reader" tool but can be easily extended to become a "writer" one. I don't have any particular interest in maintaining it, so if you or somebody else has a better idea I would be happy to work on it. Bye, Giovanni 2014-09-23 23:09 GMT+02:00 Will Yardley : >> Anyway there are some convenience functions in the >> ldap3.extend.standard namespace that act as you intend. In the case of >> "paged" searches you can get the result back directly in the search >> operation that act as a generator (or an accumulator). For example you >> can have: >> >> # simple paged search with generator - useful when returning a big dataset >> for response in self.connection.extend.standard.paged_search('o=test', >> '(cn=*)'): >> do_whatever_with(response) > > This seems much easier than, and preferable to, the first example in > your documentation, which looks similar to the example for dealing with > paged results in python-ldap. > > However, given how common search result limits are with the default > configs of modern LDAP implementations, both AD and other systems like > 389, I wonder if it wouldn't be easier (from the standpoint of > end-users) to just have an option to the connection and / or the query > that lets you set the # of max results per query, i.e.,, why not just > let the user specify 'paged_size=1000' and let the code handle how to > deal with that in a less exposed way. If it's set for the connection, > the limit would apply to all searches, and if it's set for the search, > it would apply to that search. That way, instead of having to call, > e.g., > > connection.extend.standard.paged_search('o=test', '(cn=*)', paged_size=1000) > you can just call > search('o=test', '(cn=*)', paged_size=1000) > > and then have the results presented in a data structure in the same way > an unpaged search would be. > > I do think that feedback from people with more distance from the module, > both ordinary users and developers of other modules, might be handy. > While python-ldap has a lot of flaws IMHO, and I've long been surprised > at some of the things it can't do natively, if something's going to > replace it, I'd love to see it be something that is easy to use as well > as powerful -- the ease of use and consistency of modules is one of the > things that I think makes Python strong. And, while there might be some > pain in changing interfaces or maintaining backwards compatibility now, > it's nothing compared to what it will be once the project is more widely > used. > > To me, imaplib and smtplib (while they do somewhat different types of > things) are great examples of modules that are powerful, flexible, but > also very easy to use for simple use-cases, and have a very logical > interface. Someone with fairly little understanding of the protocol can > configure them to receive / send mail with just a few configuration > options (see, > https://docs.python.org/2/library/imaplib.html#imap4-example). But in > cases where you need to directly access a particular method to, for > example, start a session and send RCPT TO, without actually sending a > message, it's also very easy to deal with. > > And, as I've mentioned before, I think figuring out some more abstract > way to represent search filters would be really great, though I will > admit to not knowing exactly how such a layer would look. I don't find > the current one very logical personally, and from what I understand, > there are a few types of combinations that can't be represented using > it. > > w > > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap From bstinson at ksu.edu Sun Oct 26 03:28:17 2014 From: bstinson at ksu.edu (Brian Stinson) Date: Sat, 25 Oct 2014 21:28:17 -0500 Subject: [python3-ldap] Library name change? In-Reply-To: Message-ID: <20141026022817.GB429@byrd.math.ksu.edu> Hi All, I'd like to jump in on this thread to introduce myself and add a thought to the library name discussion. My name is Brian Stinson and I've been using python3-ldap for a while in some of our applications at $WORK. I'm considering packaging python3-ldap for Fedora[1] and EPEL[2]. For distribution packages the Fedora best practices have the RPM name in the format: python-{name_of_module_when_importing}. In this case, that means that python3-ldap would be packaged in Fedora and EPEL as python-ldap3. I'm looking forward to participating here in the future! Brian [1]: http://fedoraproject.org [2]: http://fedoraproject.org/wiki/EPEL -- Brian Stinson bstinson at ksu.edu | IRC: bstinson | Bitbucket/Twitter: bstinsonmhk From michael at stroeder.com Sun Oct 26 10:33:19 2014 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Sun, 26 Oct 2014 10:33:19 +0100 Subject: [python3-ldap] Library name change? In-Reply-To: <20141026022817.GB429@byrd.math.ksu.edu> References: <20141026022817.GB429@byrd.math.ksu.edu> Message-ID: <544CBFDF.1040100@stroeder.com> Brian Stinson wrote: > I'm considering packaging python3-ldap for Fedora[1] and EPEL[2]. For > distribution packages the Fedora best practices have the RPM name in the > format: python-{name_of_module_when_importing}. In this case, that means > that python3-ldap would be packaged in Fedora and EPEL as python-ldap3. Some Linux distributions use the package name prefix "python3-" for modules installed for Python 3 to distinguish them from packages installed for Python 2.x. I don't know how it's on Fedora though. Ciao, Michael. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4252 bytes Desc: S/MIME Cryptographic Signature URL: From bstinson at ksu.edu Sun Oct 26 17:24:33 2014 From: bstinson at ksu.edu (Brian Stinson) Date: Sun, 26 Oct 2014 11:24:33 -0500 Subject: [python3-ldap] Library name change? In-Reply-To: <544CBFDF.1040100@stroeder.com> References: <20141026022817.GB429@byrd.math.ksu.edu> <544CBFDF.1040100@stroeder.com> Message-ID: <20141026162433.GC429@byrd.math.ksu.edu> On Oct 26 10:33, Michael Str?der wrote: > Brian Stinson wrote: > > I'm considering packaging python3-ldap for Fedora[1] and EPEL[2]. For > > distribution packages the Fedora best practices have the RPM name in the > > format: python-{name_of_module_when_importing}. In this case, that means > > that python3-ldap would be packaged in Fedora and EPEL as python-ldap3. > > Some Linux distributions use the package name prefix "python3-" for modules > installed for Python 3 to distinguish them from packages installed for Python > 2.x. I don't know how it's on Fedora though. > > Ciao, Michael. > Indeed, that's the situation in Fedora. For example, python-ldap3 would be the RPM package name when it is installed under python 2.x and python3-ldap3 for when it's installed under python 3.x Cheers! Brian -- Brian Stinson bstinson at ksu.edu | IRC: bstinson | Bitbucket/Twitter: bstinsonmhk From python3ldap at gmail.com Sun Oct 26 21:17:16 2014 From: python3ldap at gmail.com (python3ldap) Date: Sun, 26 Oct 2014 21:17:16 +0100 Subject: [python3-ldap] Library name change? In-Reply-To: <20141026162433.GC429@byrd.math.ksu.edu> References: <20141026022817.GB429@byrd.math.ksu.edu> <544CBFDF.1040100@stroeder.com> <20141026162433.GC429@byrd.math.ksu.edu> Message-ID: Hello Brian, Thank for your message, the python3-ldap codebase is exactly the same regardless of the Python version. You should not need two different packages for python3-ldap. What is the best practice for Fedora in this case? Anyway I would suggest to wait for the upcoming 0.9.6 version of python3-ldap before packaging it because it has many fixes and some new features. I think I will be able to release it for the next week. Bye, Giovanni Il domenica 26 ottobre 2014, Brian Stinson ha scritto: > On Oct 26 10:33, Michael Str?der wrote: > > Brian Stinson wrote: > > > I'm considering packaging python3-ldap for Fedora[1] and EPEL[2]. For > > > distribution packages the Fedora best practices have the RPM name in > the > > > format: python-{name_of_module_when_importing}. In this case, that > means > > > that python3-ldap would be packaged in Fedora and EPEL as python-ldap3. > > > > Some Linux distributions use the package name prefix "python3-" for > modules > > installed for Python 3 to distinguish them from packages installed for > Python > > 2.x. I don't know how it's on Fedora though. > > > > Ciao, Michael. > > > > Indeed, that's the situation in Fedora. For example, python-ldap3 would > be the RPM package name when it is installed under python 2.x and > python3-ldap3 for when it's installed under python 3.x > > Cheers!hello brian > Brian > > -- > Brian Stinson > bstinson at ksu.edu | IRC: bstinson | Bitbucket/Twitter: > bstinsonmhk > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mr.gary.waters at gmail.com Mon Oct 27 06:51:25 2014 From: mr.gary.waters at gmail.com (Gary Waters) Date: Sun, 26 Oct 2014 22:51:25 -0700 Subject: [python3-ldap] Library name change? In-Reply-To: References: <20141026022817.GB429@byrd.math.ksu.edu> <544CBFDF.1040100@stroeder.com> <20141026162433.GC429@byrd.math.ksu.edu> Message-ID: Giovanni - He is doing this because of how Redhat manages different versions of Python, even though, it is the same code, the site-packages location for python27 and python3x are different and thus the packages are named differently. Brian, I have already packaged this up and pyasn for my RHEL6 system's with python27, if you keep me in the changelog, I can email you the SRC rpms. =D Regards, Gary On Sun, Oct 26, 2014 at 1:17 PM, python3ldap wrote: > Hello Brian, > Thank for your message, the python3-ldap codebase is exactly the same > regardless of the Python version. You should not need two different > packages for python3-ldap. What is the best practice for Fedora in this > case? > > Anyway I would suggest to wait for the upcoming 0.9.6 version of > python3-ldap before packaging it because it has many fixes and some new > features. I think I will be able to release it for the next week. > > Bye, > Giovanni > > Il domenica 26 ottobre 2014, Brian Stinson ha scritto: > >> On Oct 26 10:33, Michael Str?der wrote: >> > Brian Stinson wrote: >> > > I'm considering packaging python3-ldap for Fedora[1] and EPEL[2]. For >> > > distribution packages the Fedora best practices have the RPM name in >> the >> > > format: python-{name_of_module_when_importing}. In this case, that >> means >> > > that python3-ldap would be packaged in Fedora and EPEL as >> python-ldap3. >> > >> > Some Linux distributions use the package name prefix "python3-" for >> modules >> > installed for Python 3 to distinguish them from packages installed for >> Python >> > 2.x. I don't know how it's on Fedora though. >> > >> > Ciao, Michael. >> > >> >> Indeed, that's the situation in Fedora. For example, python-ldap3 would >> be the RPM package name when it is installed under python 2.x and >> python3-ldap3 for when it's installed under python 3.x >> >> Cheers!hello brian >> Brian >> >> -- >> Brian Stinson >> bstinson at ksu.edu | IRC: bstinson | Bitbucket/Twitter: bstinsonmhk >> _______________________________________________ >> python3-ldap mailing list >> python3-ldap at python.org >> https://mail.python.org/mailman/listinfo/python3-ldap >> > > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mr.gary.waters at gmail.com Mon Oct 27 06:52:07 2014 From: mr.gary.waters at gmail.com (Gary Waters) Date: Sun, 26 Oct 2014 22:52:07 -0700 Subject: [python3-ldap] Library name change? In-Reply-To: References: <20141026022817.GB429@byrd.math.ksu.edu> <544CBFDF.1040100@stroeder.com> <20141026162433.GC429@byrd.math.ksu.edu> Message-ID: Should we add the spec file to Giovanni's s files for others to rebuild later on ? -Gary On Sun, Oct 26, 2014 at 10:51 PM, Gary Waters wrote: > Giovanni - He is doing this because of how Redhat manages different > versions of Python, even though, it is the same code, the site-packages > location for python27 and python3x are different and thus the packages are > named differently. > > Brian, > I have already packaged this up and pyasn for my RHEL6 system's with > python27, if you keep me in the changelog, I can email you the SRC rpms. =D > > Regards, > Gary > > On Sun, Oct 26, 2014 at 1:17 PM, python3ldap > wrote: > >> Hello Brian, >> Thank for your message, the python3-ldap codebase is exactly the same >> regardless of the Python version. You should not need two different >> packages for python3-ldap. What is the best practice for Fedora in this >> case? >> >> Anyway I would suggest to wait for the upcoming 0.9.6 version of >> python3-ldap before packaging it because it has many fixes and some new >> features. I think I will be able to release it for the next week. >> >> Bye, >> Giovanni >> >> Il domenica 26 ottobre 2014, Brian Stinson ha scritto: >> >>> On Oct 26 10:33, Michael Str?der wrote: >>> > Brian Stinson wrote: >>> > > I'm considering packaging python3-ldap for Fedora[1] and EPEL[2]. >>> For >>> > > distribution packages the Fedora best practices have the RPM name in >>> the >>> > > format: python-{name_of_module_when_importing}. In this case, that >>> means >>> > > that python3-ldap would be packaged in Fedora and EPEL as >>> python-ldap3. >>> > >>> > Some Linux distributions use the package name prefix "python3-" for >>> modules >>> > installed for Python 3 to distinguish them from packages installed for >>> Python >>> > 2.x. I don't know how it's on Fedora though. >>> > >>> > Ciao, Michael. >>> > >>> >>> Indeed, that's the situation in Fedora. For example, python-ldap3 would >>> be the RPM package name when it is installed under python 2.x and >>> python3-ldap3 for when it's installed under python 3.x >>> >>> Cheers!hello brian >>> Brian >>> >>> -- >>> Brian Stinson >>> bstinson at ksu.edu | IRC: bstinson | Bitbucket/Twitter: bstinsonmhk >>> _______________________________________________ >>> python3-ldap mailing list >>> python3-ldap at python.org >>> https://mail.python.org/mailman/listinfo/python3-ldap >>> >> >> _______________________________________________ >> python3-ldap mailing list >> python3-ldap at python.org >> https://mail.python.org/mailman/listinfo/python3-ldap >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bstinson at ksu.edu Mon Oct 27 14:39:09 2014 From: bstinson at ksu.edu (Brian Stinson) Date: Mon, 27 Oct 2014 08:39:09 -0500 Subject: [python3-ldap] Library name change? In-Reply-To: References: <20141026022817.GB429@byrd.math.ksu.edu> <544CBFDF.1040100@stroeder.com> <20141026162433.GC429@byrd.math.ksu.edu> Message-ID: <20141027133909.GC24033@hopper.math.ksu.edu> Hi Gary, I would be happy to merge your spec and mine, and include you in the Fedora/EPEL changelog (if you or anyone else on the list is a Fedora contributor, I'm happy to co-maintain as well). I may have to make some changes to the spec for everything to work properly across all versions, but I'll be sure to link the package review here after it's submitted in case anyone would like to comment. Brian On Oct 26 22:51, Gary Waters wrote: > Giovanni - He is doing this because of how Redhat manages different > versions of Python, even though, it is the same code, the site-packages > location for python27 and python3x are different and thus the packages are > named differently. > > Brian, > I have already packaged this up and pyasn for my RHEL6 system's with > python27, if you keep me in the changelog, I can email you the SRC rpms. =D > > Regards, > Gary > > On Sun, Oct 26, 2014 at 1:17 PM, python3ldap wrote: > > > Hello Brian, > > Thank for your message, the python3-ldap codebase is exactly the same > > regardless of the Python version. You should not need two different > > packages for python3-ldap. What is the best practice for Fedora in this > > case? > > > > Anyway I would suggest to wait for the upcoming 0.9.6 version of > > python3-ldap before packaging it because it has many fixes and some new > > features. I think I will be able to release it for the next week. > > > > Bye, > > Giovanni > > > > Il domenica 26 ottobre 2014, Brian Stinson ha scritto: > > > >> On Oct 26 10:33, Michael Str?der wrote: > >> > Brian Stinson wrote: > >> > > I'm considering packaging python3-ldap for Fedora[1] and EPEL[2]. For > >> > > distribution packages the Fedora best practices have the RPM name in > >> the > >> > > format: python-{name_of_module_when_importing}. In this case, that > >> means > >> > > that python3-ldap would be packaged in Fedora and EPEL as > >> python-ldap3. > >> > > >> > Some Linux distributions use the package name prefix "python3-" for > >> modules > >> > installed for Python 3 to distinguish them from packages installed for > >> Python > >> > 2.x. I don't know how it's on Fedora though. > >> > > >> > Ciao, Michael. > >> > > >> > >> Indeed, that's the situation in Fedora. For example, python-ldap3 would > >> be the RPM package name when it is installed under python 2.x and > >> python3-ldap3 for when it's installed under python 3.x > >> > >> Cheers!hello brian > >> Brian > >> > >> -- > >> Brian Stinson > >> bstinson at ksu.edu | IRC: bstinson | Bitbucket/Twitter: bstinsonmhk > >> _______________________________________________ > >> python3-ldap mailing list > >> python3-ldap at python.org > >> https://mail.python.org/mailman/listinfo/python3-ldap > >> > > > > _______________________________________________ > > python3-ldap mailing list > > python3-ldap at python.org > > https://mail.python.org/mailman/listinfo/python3-ldap > > > > From python3ldap at gmail.com Mon Oct 27 18:57:21 2014 From: python3ldap at gmail.com (python3ldap) Date: Mon, 27 Oct 2014 18:57:21 +0100 Subject: [python3-ldap] Library name change? In-Reply-To: References: <20141026022817.GB429@byrd.math.ksu.edu> <544CBFDF.1040100@stroeder.com> <20141026162433.GC429@byrd.math.ksu.edu> Message-ID: Hi Gary, thanks for your explanation. Now the reason for the two different packages is clear to me. I'm still not sure which is the best way to fulfill Brian's request. We could leave the package name as is (python3-ldap) and let the distribution mantainers package it with different names. Or we could change the name to follow the rule "python" plus (that I find quite resonable). I see a possible name clash with the former python-ldap from Michael Stroeder because the two libraries are (still) not compatible: python-ldap3 should be misinterpreted as a newer release of python-ldap. It should be useful to know if Michael has intention to port its library to python3 officially or not, because in the latter case we could use that name anyway. Bye, Giovanni 2014-10-27 6:51 GMT+01:00 Gary Waters : > Giovanni - He is doing this because of how Redhat manages different versions > of Python, even though, it is the same code, the site-packages location for > python27 and python3x are different and thus the packages are named > differently. > > Brian, > I have already packaged this up and pyasn for my RHEL6 system's with > python27, if you keep me in the changelog, I can email you the SRC rpms. =D > > Regards, > Gary > > On Sun, Oct 26, 2014 at 1:17 PM, python3ldap wrote: >> >> Hello Brian, >> Thank for your message, the python3-ldap codebase is exactly the same >> regardless of the Python version. You should not need two different packages >> for python3-ldap. What is the best practice for Fedora in this case? >> >> Anyway I would suggest to wait for the upcoming 0.9.6 version of >> python3-ldap before packaging it because it has many fixes and some new >> features. I think I will be able to release it for the next week. >> >> Bye, >> Giovanni >> >> Il domenica 26 ottobre 2014, Brian Stinson ha scritto: >>> >>> On Oct 26 10:33, Michael Str?der wrote: >>> > Brian Stinson wrote: >>> > > I'm considering packaging python3-ldap for Fedora[1] and EPEL[2]. >>> > > For >>> > > distribution packages the Fedora best practices have the RPM name in >>> > > the >>> > > format: python-{name_of_module_when_importing}. In this case, that >>> > > means >>> > > that python3-ldap would be packaged in Fedora and EPEL as >>> > > python-ldap3. >>> > >>> > Some Linux distributions use the package name prefix "python3-" for >>> > modules >>> > installed for Python 3 to distinguish them from packages installed for >>> > Python >>> > 2.x. I don't know how it's on Fedora though. >>> > >>> > Ciao, Michael. >>> > >>> >>> Indeed, that's the situation in Fedora. For example, python-ldap3 would >>> be the RPM package name when it is installed under python 2.x and >>> python3-ldap3 for when it's installed under python 3.x >>> >>> Cheers!hello brian >>> Brian >>> >>> -- >>> Brian Stinson >>> bstinson at ksu.edu | IRC: bstinson | Bitbucket/Twitter: bstinsonmhk >>> _______________________________________________ >>> python3-ldap mailing list >>> python3-ldap at python.org >>> https://mail.python.org/mailman/listinfo/python3-ldap >> >> >> _______________________________________________ >> python3-ldap mailing list >> python3-ldap at python.org >> https://mail.python.org/mailman/listinfo/python3-ldap >> > From michael at stroeder.com Mon Oct 27 20:13:49 2014 From: michael at stroeder.com (=?UTF-8?B?TWljaGFlbCBTdHLDtmRlcg==?=) Date: Mon, 27 Oct 2014 20:13:49 +0100 Subject: [python3-ldap] Library name change? In-Reply-To: References: <20141026022817.GB429@byrd.math.ksu.edu> <544CBFDF.1040100@stroeder.com> <20141026162433.GC429@byrd.math.ksu.edu> Message-ID: <544E996D.5060508@stroeder.com> python3ldap wrote: > I see a possible name clash with the former python-ldap from Michael > Stroeder because the two libraries are (still) not compatible: > python-ldap3 should be misinterpreted as a newer release of > python-ldap. It should be useful to know if Michael has intention to > port its library to python3 officially or not, because in the latter > case we could use that name anyway. I definitely want to avoid name clashes since there may be a python-ldap release for Python3 in the future. The following module name spaces are used by python-ldap: ldap ldif dsml ldapurl So please rename to something else. Though I definitely expect people to confuse package names: python-ldap3-0.9 with python-ldap-3.0 and python3-ldap3-0.9 with python3-ldap-3.0 Ciao, Michael. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4252 bytes Desc: S/MIME Cryptographic Signature URL: From python3ldap at gmail.com Tue Oct 28 17:15:40 2014 From: python3ldap at gmail.com (Python3-ldap) Date: Tue, 28 Oct 2014 17:15:40 +0100 Subject: [python3-ldap] R: Library name change? In-Reply-To: <544E996D.5060508@stroeder.com> References: <20141026022817.GB429@byrd.math.ksu.edu> <544CBFDF.1040100@stroeder.com> <20141026162433.GC429@byrd.math.ksu.edu> <544E996D.5060508@stroeder.com> Message-ID: <544fc12f.676ab40a.05a7.5bfa@mx.google.com> I agree with Michael, to avoid clashes I prefer to keep the current name for the library. Obviously this regards the package on pypi only, distribution mantainers are free to follow best practices for their distributions. Bye, Giovanni ----- Messaggio originale ----- Da: "Michael Str?der" Inviato: ?27/?10/?2014 20:13 A: "python3ldap" Cc: "python3-ldap at python.org" Oggetto: Re: [python3-ldap] Library name change? python3ldap wrote: > I see a possible name clash with the former python-ldap from Michael > Stroeder because the two libraries are (still) not compatible: > python-ldap3 should be misinterpreted as a newer release of > python-ldap. It should be useful to know if Michael has intention to > port its library to python3 officially or not, because in the latter > case we could use that name anyway. I definitely want to avoid name clashes since there may be a python-ldap release for Python3 in the future. The following module name spaces are used by python-ldap: ldap ldif dsml ldapurl So please rename to something else. Though I definitely expect people to confuse package names: python-ldap3-0.9 with python-ldap-3.0 and python3-ldap3-0.9 with python3-ldap-3.0 Ciao, Michael. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bstinson at ksu.edu Tue Oct 28 19:31:34 2014 From: bstinson at ksu.edu (Brian Stinson) Date: Tue, 28 Oct 2014 13:31:34 -0500 Subject: [python3-ldap] R: Library name change? In-Reply-To: <544fc12f.676ab40a.05a7.5bfa@mx.google.com> References: <20141026022817.GB429@byrd.math.ksu.edu> <544CBFDF.1040100@stroeder.com> <20141026162433.GC429@byrd.math.ksu.edu> <544E996D.5060508@stroeder.com> <544fc12f.676ab40a.05a7.5bfa@mx.google.com> Message-ID: <20141028183133.GH20662@hopper.math.ksu.edu> Would python-python3ldap and python3-python3ldap be more acceptable distro package names? That might help reduce any confusion with Michael's python-ldap Brian -- Brian Stinson bstinson at ksu.edu | IRC: bstinson | Bitbucket/Twitter: bstinsonmhk On Oct 28 17:15, Python3-ldap wrote: > I agree with Michael, to avoid clashes I prefer to keep the current name for the library. Obviously this regards the package on pypi only, distribution mantainers are free to follow best practices for their distributions. > > Bye, > Giovanni > > ----- Messaggio originale ----- > Da: "Michael Str?der" > Inviato: ?27/?10/?2014 20:13 > A: "python3ldap" > Cc: "python3-ldap at python.org" > Oggetto: Re: [python3-ldap] Library name change? > > python3ldap wrote: > > I see a possible name clash with the former python-ldap from Michael > > Stroeder because the two libraries are (still) not compatible: > > python-ldap3 should be misinterpreted as a newer release of > > python-ldap. It should be useful to know if Michael has intention to > > port its library to python3 officially or not, because in the latter > > case we could use that name anyway. > > I definitely want to avoid name clashes since there may be a python-ldap > release for Python3 in the future. > > The following module name spaces are used by python-ldap: > ldap > ldif > dsml > ldapurl > > So please rename to something else. > > Though I definitely expect people to confuse package names: > python-ldap3-0.9 with python-ldap-3.0 and > python3-ldap3-0.9 with python3-ldap-3.0 > > Ciao, Michael. > > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap From python3ldap at gmail.com Wed Oct 29 06:03:39 2014 From: python3ldap at gmail.com (Python3-ldap) Date: Wed, 29 Oct 2014 06:03:39 +0100 Subject: [python3-ldap] R: R: Library name change? In-Reply-To: <20141028183133.GH20662@hopper.math.ksu.edu> References: <20141026022817.GB429@byrd.math.ksu.edu> <544CBFDF.1040100@stroeder.com> <20141026162433.GC429@byrd.math.ksu.edu> <544E996D.5060508@stroeder.com> <544fc12f.676ab40a.05a7.5bfa@mx.google.com> <20141028183133.GH20662@hopper.math.ksu.edu> Message-ID: <54507534.2ec6b40a.4aca.6b6f@mx.google.com> I find these names over confusing. Can't you use something like python-ldap3-ng and python3-ldap3-ng? I've seen this often when a new implementation is quite different from the previous one. Bye, Giovanni ----- Messaggio originale ----- Da: "Brian Stinson" Inviato: ?28/?10/?2014 19:31 A: "Python3-ldap" Cc: "Michael Str?der" ; "python3-ldap at python.org" Oggetto: Re: [python3-ldap] R: Library name change? Would python-python3ldap and python3-python3ldap be more acceptable distro package names? That might help reduce any confusion with Michael's python-ldap Brian -- Brian Stinson bstinson at ksu.edu | IRC: bstinson | Bitbucket/Twitter: bstinsonmhk On Oct 28 17:15, Python3-ldap wrote: > I agree with Michael, to avoid clashes I prefer to keep the current name for the library. Obviously this regards the package on pypi only, distribution mantainers are free to follow best practices for their distributions. > > Bye, > Giovanni > > ----- Messaggio originale ----- > Da: "Michael Str?der" > Inviato: ?27/?10/?2014 20:13 > A: "python3ldap" > Cc: "python3-ldap at python.org" > Oggetto: Re: [python3-ldap] Library name change? > > python3ldap wrote: > > I see a possible name clash with the former python-ldap from Michael > > Stroeder because the two libraries are (still) not compatible: > > python-ldap3 should be misinterpreted as a newer release of > > python-ldap. It should be useful to know if Michael has intention to > > port its library to python3 officially or not, because in the latter > > case we could use that name anyway. > > I definitely want to avoid name clashes since there may be a python-ldap > release for Python3 in the future. > > The following module name spaces are used by python-ldap: > ldap > ldif > dsml > ldapurl > > So please rename to something else. > > Though I definitely expect people to confuse package names: > python-ldap3-0.9 with python-ldap-3.0 and > python3-ldap3-0.9 with python3-ldap-3.0 > > Ciao, Michael. > > _______________________________________________ > python3-ldap mailing list > python3-ldap at python.org > https://mail.python.org/mailman/listinfo/python3-ldap -------------- next part -------------- An HTML attachment was scrubbed... URL: From dnoble at splunk.com Fri Oct 31 23:03:01 2014 From: dnoble at splunk.com (David Noble) Date: Fri, 31 Oct 2014 22:03:01 +0000 Subject: [python3-ldap] What's the best way to deal with continuation referrals? Message-ID: I see this is on your roadmap and I?m hopeful that you've got the infrastructure in place to follow continuation referrals. I?ve now got access to an active directory server that?s responding with continuation referrals in search results; items that look like this: {'type': 'searchResRef', 'uri': ['ldap://ForestDnsZones.chubbybunny.local/DC=ForestDnsZones,DC=chubbybunny,DC=local']} {'type': 'searchResRef', 'uri': ['ldap://DomainDnsZones.chubbybunny.local/DC=DomainDnsZones,DC=chubbybunny,DC=local']} {'type': 'searchResRef', 'uri': ['ldap://chubbybunny.local/CN=Configuration,DC=chubbybunny,DC=local']} Can I follow these referrals with ldap3? Best, David Noble -------------- next part -------------- An HTML attachment was scrubbed... URL: From python3ldap at gmail.com Sat Nov 1 10:57:57 2014 From: python3ldap at gmail.com (python3ldap) Date: Sat, 1 Nov 2014 10:57:57 +0100 Subject: [python3-ldap] Python3-ldap 0.9.6 released Message-ID: Hello, I've released version 0.9.6 of python3-ldap. It includes two new features, some enanchement for Active Directory and a bunch of bug fixes. The new features are "offline" schemas and json serialization for server and searches. Now you can save the dsa info and schema info in a json string or file and use it later to recreate a server object with the same features. This is useful when the ldap server is not returning the schema or dsa info and is required by the RFCs that state that the client must not send operation with attributes or syntaxes not know to the server. To accomplish this you can use the server.info.to_json(), server.info.to_file(), server.schema.to_json() and server.schema.to_file() to have the dsa info and the schema info in a json format. The library strives for keep the information in json consistent with the representation in the original format of binary data received by the server, but must reformat binary attributes to a b64encoded format for saving it a string or a file. This reformatting should be trasparent to you, and independent from the python version (python 2 or 3 generated json files are interchangeable). You can also load a JSON serialized server definition with the Server.from_json() and Server.from_file() methods. The real server must anyway exist or you get an address exception. The dsa info will be updated with real info from server while the schema will remain the one you defined. I've included the new package ldap3.protocol.schemas with some ldap definition from Novell eDirectory, Active Directory and Openldap (schema are gotten from a fresh installation), more schema will probably come. This machinery (even if it is supposed to exist by the LDAP RFCs) is not really useful (at least this is for me) but it's helpful for the "mocking" strategy I plan to include in the next release. It should let you to perform tests without any real ldap server (as with mockldap). Json serialization for response search let you have a fast way to save entries from responses in a json form. You have now the response_to_json() and response_to_file() in the Connection object that let you sve the entries from a search operation. You can specify the raw=True parameter to include the raw attributes from the response. Binary attributes are b64encoded or properly formatted is their syntax is known. I've added some default formatters for Active Directory syntaxes. Now the date attributes are formatted to a datetime object and the sid and guid are properly converted as specified in Microsoft documentation. I apologize for the outdated documentation, I plan to have new docs soon. This is the changelog for 0.9.6: * 0.9.6 2014.11.01 - New feature 'offline schema' to let the client have knowledge of schema and DSA info even if not returned by the server - Offline schema for Novell eDirectory 8.8.8 - Offline schema for Microsoft Active Directory 2012 R2 - Offline schema for slapd 2.4 (Openldap) - Added server.info.to_json() and server.info.to_file to JSON serialize schema and info from Server object - Added Server.from_json() and Server.from_file() to create a Server object from a JSON definition - Added response_to_json() and response_to_file() to Connection object to serialize search response entries in JSON as a string or as a file - New exception hierarchy LDAPConfigurationError includes library configuration exceptions - New exception LDAPInvalidConfigurationDefinitionError - Dsa info and schema are not read twice when binding (thanks phobie) - LDAPStartTLSError exception is merged with exception raised from ssl packaged - Digest-MD5 SASL authentication accepts directives with list attributes (thanks John) - Fixed caseInsensitiveDictionary for keys() and values() methods - Fixed matching of certificate name in ssl with Python2 - Attributes names and formatters are checked even if schema is not read by the server - Fixed fractional time when parsing generalized time - Specific decoder for Active Directory ObjectGuid and ObjectSid - Added additional checking for unicode in Python 2 - Tested against python 3.4.2 - Updated setuptools to 7.0 Bye, Giovanni From python3ldap at gmail.com Sat Nov 1 12:44:19 2014 From: python3ldap at gmail.com (Python3-ldap) Date: Sat, 1 Nov 2014 12:44:19 +0100 Subject: [python3-ldap] R: What's the best way to deal with continuationreferrals? In-Reply-To: References: Message-ID: <5454c7ab.235ec20a.7b18.ffff9722@mx.google.com> hi David, I've set up an infrastructure for testing different LDAP servers, I think I should be able to include automatic continuation referral resolution in one of the next releases of python3-ldap. Bye, Giovanni ----- Messaggio originale ----- Da: "David Noble" Inviato: ?01/?11/?2014 10:02 A: "python3-ldap at python.org" Oggetto: [python3-ldap] What's the best way to deal with continuationreferrals? I see this is on your roadmap and I?m hopeful that you've got the infrastructure in place to follow continuation referrals. I?ve now got access to an active directory server that?s responding with continuation referrals in search results; items that look like this:{'type': 'searchResRef', 'uri': ['ldap://ForestDnsZones.chubbybunny.local/DC=ForestDnsZones,DC=chubbybunny,DC=local']}{'type': 'searchResRef', 'uri': ['ldap://DomainDnsZones.chubbybunny.local/DC=DomainDnsZones,DC=chubbybunny,DC=local']}{'type': 'searchResRef', 'uri': ['ldap://chubbybunny.local/CN=Configuration,DC=chubbybunny,DC=local']}Can I follow these referrals with ldap3? Best, David Noble -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at stroeder.com Sat Nov 1 13:29:04 2014 From: michael at stroeder.com (=?ISO-8859-1?Q?Michael_Str=F6der?=) Date: Sat, 01 Nov 2014 13:29:04 +0100 Subject: [python3-ldap] R: What's the best way to deal with continuationreferrals? In-Reply-To: <5454c7ab.235ec20a.7b18.ffff9722@mx.google.com> References: <5454c7ab.235ec20a.7b18.ffff9722@mx.google.com> Message-ID: <5454D210.508@stroeder.com> Python3-ldap wrote: > I've set up an infrastructure for testing different LDAP servers, I think I > should be able to include automatic continuation referral resolution in > one of the next releases of python3-ldap. Note that in general LDAPv3 referrals are a broken concept anyway and not used. Especially since there's no standard defining e.g. which authentication to use when following a referral. So IMO it's ok at the API level to just return the referral LDAP URLs and let the LDAP client application deal with it because the app has more knowledge about the context. With MS AD I wildly guess that "the concept" was to let the client simply re-use the Windows logon identity. But even with MS AD you won't need chasing referrals. Everybody who thinks so should have a closer look what's really referenced by the referrals. In my web2ldap I simply present an input form to the user interactively asking for the authc information to using when chasing the referral. BTW: This functionality was implemented for an academic approach ~14 years ago. Chasing referrals has never been required since then. Referrals e.g. returned for write requests should also be handled by the LDAP server with chaining. Ciao, Michael. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4252 bytes Desc: S/MIME Cryptographic Signature URL: From dnoble at splunk.com Sat Nov 1 19:31:38 2014 From: dnoble at splunk.com (David Noble) Date: Sat, 1 Nov 2014 18:31:38 +0000 Subject: [python3-ldap] R: What's the best way to deal with continuationreferrals? In-Reply-To: <5454c7ab.235ec20a.7b18.ffff9722@mx.google.com> References: , <5454c7ab.235ec20a.7b18.ffff9722@mx.google.com> Message-ID: <93F39EEE-D9E2-43E6-AD74-A14CD284D2E7@splunk.com> Thanks, that's good news. How might I follow the referrals myself today? Sent from my iPhone On Nov 1, 2014, at 4:44 AM, Python3-ldap > wrote: hi David, I've set up an infrastructure for testing different LDAP servers, I think I should be able to include automatic continuation referral resolution in one of the next releases of python3-ldap. Bye, Giovanni ________________________________ Da: David Noble Inviato: ?01/?11/?2014 10:02 A: python3-ldap at python.org Oggetto: [python3-ldap] What's the best way to deal with continuationreferrals? I see this is on your roadmap and I?m hopeful that you've got the infrastructure in place to follow continuation referrals. I?ve now got access to an active directory server that?s responding with continuation referrals in search results; items that look like this: {'type': 'searchResRef', 'uri': ['ldap://ForestDnsZones.chubbybunny.local/DC=ForestDnsZones,DC=chubbybunny,DC=local']} {'type': 'searchResRef', 'uri': ['ldap://DomainDnsZones.chubbybunny.local/DC=DomainDnsZones,DC=chubbybunny,DC=local']} {'type': 'searchResRef', 'uri': ['ldap://chubbybunny.local/CN=Configuration,DC=chubbybunny,DC=local']} Can I follow these referrals with ldap3? Best, David Noble -------------- next part -------------- An HTML attachment was scrubbed... URL: From python3ldap at gmail.com Sat Nov 1 20:35:32 2014 From: python3ldap at gmail.com (python3ldap) Date: Sat, 1 Nov 2014 20:35:32 +0100 Subject: [python3-ldap] R: What's the best way to deal with continuationreferrals? In-Reply-To: <5454D210.508@stroeder.com> References: <5454c7ab.235ec20a.7b18.ffff9722@mx.google.com> <5454D210.508@stroeder.com> Message-ID: Hello Michael, David, with the auto_referral=True parameter in the connection object python3-ldap let you automatically follow referrals in result code only You must specify a list of "trusted" ldap server in the Server object. for each referral server you can specify if you want send authentication data or try only an anonymous bind. This kind of referral is in the result message and can be returned for every operation. It means that the server is not able to perform the operation requested and it suggest another server that should be able to. The other server can again return a referral and so on. The RFCs state that the client must avoid loop in referrals and allow a maximum of 10 "hops". This is honored by python3-ldap. What is still missing in python3-ldap is the "continuation references" that can be returned in a search operation as a searchResponse. I should follow the same approach (specify a list of server with auth or anonymous bind) but the problem here is that you can have many references to different servers, so I'm not sure if this is the right way to perform the search, because the search operation could be very long. Bye, Giovanni 2014-11-01 13:29 GMT+01:00 Michael Str?der : > Python3-ldap wrote: >> I've set up an infrastructure for testing different LDAP servers, I think I >> should be able to include automatic continuation referral resolution in >> one of the next releases of python3-ldap. > > Note that in general LDAPv3 referrals are a broken concept anyway and not > used. Especially since there's no standard defining e.g. which authentication > to use when following a referral. > > So IMO it's ok at the API level to just return the referral LDAP URLs and let > the LDAP client application deal with it because the app has more knowledge > about the context. > > With MS AD I wildly guess that "the concept" was to let the client simply > re-use the Windows logon identity. But even with MS AD you won't need chasing > referrals. Everybody who thinks so should have a closer look what's really > referenced by the referrals. > > In my web2ldap I simply present an input form to the user interactively asking > for the authc information to using when chasing the referral. BTW: This > functionality was implemented for an academic approach ~14 years ago. Chasing > referrals has never been required since then. Referrals e.g. returned for > write requests should also be handled by the LDAP server with chaining. > > Ciao, Michael. > From python3ldap at gmail.com Wed Nov 12 00:16:03 2014 From: python3ldap at gmail.com (python3ldap) Date: Wed, 12 Nov 2014 00:16:03 +0100 Subject: [python3-ldap] python3-ldap 0.9.6.1 Message-ID: I've released the 0.9.6.1 version of python3-ldap. I've fixed a problem in the source distribution package and added the Fedora389 Directory Server v 1.3.3.0 to the offline schemas. You can get the server with Server('servername', get_info=ldap3.OFFLINE_DS389_1_3_3 I've also included an "auto_range" parameter to get long attribute value list. the connection object if you get an attribute result in the form of "attribute;range=1-1500' this means that the server has more element for the attribute values but you have to send other searches operation until you get the 'attribute;range=9999-*' format. If you set auto_range to True python3-ldap will perform all the needed search operations in the same request and will reassemble the result in the "attribute" attribute (removing the range). This is specified in RFC 3866 but I've seen it applied only on Active Directory. Let me know if this is working on other ldap servers too. The full changelog for 0.9.6.1 is: - Added boolean parameter "auto_range" to catch the "range" ldap tag in searches. When true all needed search operation are made to fully obtain the whole range of result values - Fixed bug in sdist - Added offline schema for Fedora 389 Directory Server 1.3.3 - Fixed bug while reading DSA info Bye, Giovanni From python3ldap at gmail.com Tue Nov 18 23:16:34 2014 From: python3ldap at gmail.com (python3ldap) Date: Tue, 18 Nov 2014 23:16:34 +0100 Subject: [python3-ldap] Python3-ldap: proposal for IP connection fallback Message-ID: Hello everybody, I've received a request to implement a sort of fallback from ipv6 to ipv4 in python3-ldap. The rationale is that when you specify a server name python3-ldap queries the DNS service to resolve it (via getaddrinfo) and then tries to connect to the first address received (either ipv4 or ivp6). Chances are that you get a valid ipv6 but the "path" from the client and the server is not available (maybe not all ipv6 trunks are functional) so you get a connection error. The proposal is to implement a fallback to an ipv4 address if available. I received this message from Brian, a valid contributor to the library: **** Hello, Generally speaking it is standard practise to automatically fall back to IPv4 is the server doesn't support IPv6. This means the client doesn't need to know anything about the implementation status of the server, and will automatically use IPv6 if/when it becomes available. The standard behaviour, as implemented almost everywhere else is that is should automatically fall back to IPv4 if it gets connection refused. This IPv4 fallback has nothing to do with SRV records either. I do not see any reason why a python ldap binding should be a special case. However being able to override the default behaviour and force IPv6 only or force IPv4 only is also considered a good idea. *** and this message from Robert that helped me to implement the ipv6 portion of the connection: **** Hi, Ok, I stand corrected, after some research and analysis I think fallback, even active by default, may be quite a good idea, but only if implemented following something like RFC 6555 recommendation. (Happy eyeball algorithm) Results of first getaddrinfo call shouldn't be used for the lifetime of Server object, but rather cached only for a short time (like one minute) and refreshed after that as needed. So long living application won't use outdated information from DNS, but also won't waste cycles for constantly calling resolver unnecessarily. If getaddrinfo caching is implemented, Server object should probably have an option of separate internal pools for IPv4 and IPv6 and select IPs in RFC 6555 way. It should be possible to select current ROUND_ROBIN, RANDOM or FIRST strategies for each of them independently. FIRST probably default if there's at least one IPv6 address) strategy would mean that connections are always tried in order returned from most recent cached getaddrinfo call. It especially makes sense in a following scenario (tested on Debian): server has two IPv6 addresses, native 2a01::xx/16, 6to4 one and one IPv4. According to default contents of /etc/gai.conf, clients having native IPv6 will prefer server's native address as well. then 6to4, then IPv4. Clients having 6to4 address will prefer 6to4, then IPv4, then native IPv6. If both IPv6 addresses would be put into the same pool and then one of them would be selected in a round robin way for subsequent RFC 6555 procedure, in latter case connection would be tried to the least preferred address half of the time. Unfortunately, getaddrinfo doesn't give information about in what groups addresses should be splitted, there's no way of creating. For hostname having multihomed IPv4 only, ROUND_ROBIN would be the default. I think it would handle two most common scenarios: load balancing for IPv4, and graceful failover for dual stack IPv4/IPv6. It would not handle in optimal way situations when there are for example two IPv6 native and two 6to4 addresses. But IMO such scenarios should be handled by SRV records anyway. Due to 1. and 2. I'm not sure if returning ServerPool in the way it's implemented now is a good idea. First, it would treat all addresses the same not in order of preference. Second, it may be difficult to implement something like RFC 6555 on top of it properly. Third, it would be more difficult to track DNS changes. Fourth, I'm not sure if Server constructor should sometimes return object of an other class not even inherited from it. Of course you may have completely different implementation on your mind than I guessed so it may be moot point. WIth RFC 6555 implemented I would drop idea of PREFER_IPV4|PREFER_IPV6 options and provide only IPV[46]ONLY. Default strategy should be enough in most simple cases, and if short term override is needed, former options haven't any clear advantages over latter ones. And for advanced uses, tweaking system settings gives more flexibility which using of PREFER options would only limit. Regarding SRV, I'm still thinking how it should be implemented. Probably current Server class should be closer to current ServerPool implementation, maybe with introduced equivalent of current Server kept behind the scenes as less exposed internal structures. Btw. quick googling shows that at least OpenLDAP supports ldap SRVs and also MSDN mentions them, so they aren't completely exotic idea. *** The "happy eyeballs" (http://en.wikipedia.org/wiki/Happy_Eyeballs) algorithm sends parallel SYN packet to both IPv4 and IPv6 addresses and prefer IPv6 if available. This means that there is a little overhead in the connection because one of the packet will be discarded. Do you have any suggestion or idea about this topic? It's correct to address it at the python3-ldap library level or should it be resolved at the tcp level? Bye, Giovanni From python3ldap at gmail.com Fri Dec 19 22:42:04 2014 From: python3ldap at gmail.com (python3ldap) Date: Fri, 19 Dec 2014 22:42:04 +0100 Subject: [python3-ldap] Python 0.9.7 released! Message-ID: Hello, I've released the 0.9.7 release of python3-ldap. Now the library has full dual IP stack capability. You can chose to use IPv4 or IPv6 and failback to the other protocol if the server is unreachable. The library gets the ip addresses from the dns server and follows the mode specified in the "mode" parameter of the Server object: IP_SYSTEM_DEFAULT IP_V4_ONLY IP_V6_ONLY IP_V4_PREFERRED IP_V6_PREFERRED With IP_SYSTEM_DEFAULT it follow the default of the os, while with IP_V4_ONLY or IP_V6_ONLY it tries on?ly the IPs returned by the DNS server for the specified protocol. If you specify IP_V4_PREFERRED or IP_V6_PREFERRED it start with the request protocol and fail back to the other one if no connection is available. The ADDRESS_INFO_REFRESH_TIME config parameter in ldap3 namespace specifies the number of seconds before refreshing the addresses from dns. It defaults to 300 (5 minutes). I prefer this solution over RFC6555 because it let the developer decide how connection must be made. RFC 6555 is good to provide an automatic path from ipv4 to ipv6.and can eventually be implemented later in the library as an additional "mode". I've also revised the "reusable" strategy, resolving some deadlocks happening when reading the schema from different servers. Let me know if the "mode" is working, because I have limited access to IPV6 servers. Also, as requested in this mailing list I've shortened some CONSTANTS used in the Server and Connection objects definition. The former parameters are still valid and will not be deprecated. I've also revised the "reusable" strategy. It should be faster now and should avoid race conditions that randomly appears. The full changelog for 0.9.7: CHANGELOG ========= * 0.9.7 2014.12.17 - Fixed bug for auto_range used in paged search - Added dual IP stack mode parameter in Server object, values are: IP_SYSTEM_DEFAULT, IP_V4_ONLY, IP_V4_PREFERRED, IP_V6_ONLY, IP_V6_PREFERRED - Added read_server_info parameter to bind() and start_tls() to avoid multiple schema and info read operations with auto_bind - Redesigned Reusable (pooled) strategy - Added LDAPResponseTimeoutError exception raised when get_response() doesn't receive any response in the allowed timeout period - Added shortened authentication parameters in ldap3 namespace: ANONYMOUS, SIMPLE, SASL - Added shortened scope parameters in ldap3 namespace: BASE, LEVEL, SUBTREE - Added shortened get_info parameters in ldap3 namespace: NONE, DSA, SCHEMA, ALL - Added shortened alias dereferencing parameters in ldap3 namespace: DEREF_NONE, DEREF_SEARCH, DEREF_BASE, DEREF_ALWAYS - Added shortened connection strategy parameters in ldap3 namespace: SYNC, ASYNC, LDIF, RESTARTABLE, REUSABLE - Added shortened pooling strategy parameters in ldap3 namespace: FIRST, ROUND_ROBIN, RANDOM - Added reentrant lock to avoid race conditions in the Connection object - When run in Python 2.7.9 uses SSLContext - Tested against Python 2.7.9, PyPy 2.4.0 and PyPy3 2.4.0 - setuptools updated to 8.2.1 Bye, Giovanni