Show More
@@ -22,10 +22,11 b'' | |||||
22 | RhodeCode authentication plugin for LDAP |
|
22 | RhodeCode authentication plugin for LDAP | |
23 | """ |
|
23 | """ | |
24 |
|
24 | |||
25 |
|
25 | import re | ||
26 | import colander |
|
26 | import colander | |
27 | import logging |
|
27 | import logging | |
28 | import traceback |
|
28 | import traceback | |
|
29 | import string | |||
29 |
|
30 | |||
30 | from rhodecode.translation import _ |
|
31 | from rhodecode.translation import _ | |
31 | from rhodecode.authentication.base import ( |
|
32 | from rhodecode.authentication.base import ( | |
@@ -50,6 +51,9 b' except ImportError:' | |||||
50 | ldap = Missing |
|
51 | ldap = Missing | |
51 |
|
52 | |||
52 |
|
53 | |||
|
54 | class LdapError(Exception): | |||
|
55 | pass | |||
|
56 | ||||
53 | def plugin_factory(plugin_id, *args, **kwds): |
|
57 | def plugin_factory(plugin_id, *args, **kwds): | |
54 | """ |
|
58 | """ | |
55 | Factory function that is called during plugin discovery. |
|
59 | Factory function that is called during plugin discovery. | |
@@ -226,9 +230,10 b' class AuthLdap(object):' | |||||
226 | self.BASE_DN = safe_str(base_dn) |
|
230 | self.BASE_DN = safe_str(base_dn) | |
227 | self.LDAP_FILTER = safe_str(ldap_filter) |
|
231 | self.LDAP_FILTER = safe_str(ldap_filter) | |
228 |
|
232 | |||
229 |
def _get_ldap_ |
|
233 | def _get_ldap_conn(self): | |
230 | if self.debug: |
|
234 | if self.debug: | |
231 | ldap.set_option(ldap.OPT_DEBUG_LEVEL, 255) |
|
235 | ldap.set_option(ldap.OPT_DEBUG_LEVEL, 255) | |
|
236 | ||||
232 | if hasattr(ldap, 'OPT_X_TLS_CACERTDIR'): |
|
237 | if hasattr(ldap, 'OPT_X_TLS_CACERTDIR'): | |
233 | ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, |
|
238 | ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, | |
234 | '/etc/openldap/cacerts') |
|
239 | '/etc/openldap/cacerts') | |
@@ -239,21 +244,23 b' class AuthLdap(object):' | |||||
239 |
|
244 | |||
240 | if self.TLS_KIND != 'PLAIN': |
|
245 | if self.TLS_KIND != 'PLAIN': | |
241 | ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, self.TLS_REQCERT) |
|
246 | ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, self.TLS_REQCERT) | |
242 | server = ldap.initialize(self.LDAP_SERVER) |
|
247 | ||
|
248 | log.debug('initializing LDAP connection to:%s', self.LDAP_SERVER) | |||
|
249 | ldap_conn = ldap.initialize(self.LDAP_SERVER) | |||
243 | if self.ldap_version == 2: |
|
250 | if self.ldap_version == 2: | |
244 |
|
|
251 | ldap_conn.protocol = ldap.VERSION2 | |
245 | else: |
|
252 | else: | |
246 |
|
|
253 | ldap_conn.protocol = ldap.VERSION3 | |
247 |
|
254 | |||
248 | if self.TLS_KIND == 'START_TLS': |
|
255 | if self.TLS_KIND == 'START_TLS': | |
249 |
|
|
256 | ldap_conn.start_tls_s() | |
250 |
|
257 | |||
251 | if self.LDAP_BIND_DN and self.LDAP_BIND_PASS: |
|
258 | if self.LDAP_BIND_DN and self.LDAP_BIND_PASS: | |
252 | log.debug('Trying simple_bind with password and given login DN: %s', |
|
259 | log.debug('Trying simple_bind with password and given login DN: %s', | |
253 | self.LDAP_BIND_DN) |
|
260 | self.LDAP_BIND_DN) | |
254 |
|
|
261 | ldap_conn.simple_bind_s(self.LDAP_BIND_DN, self.LDAP_BIND_PASS) | |
255 |
|
262 | |||
256 |
return |
|
263 | return ldap_conn | |
257 |
|
264 | |||
258 | def get_uid(self, username): |
|
265 | def get_uid(self, username): | |
259 | uid = username |
|
266 | uid = username | |
@@ -295,13 +302,14 b' class AuthLdap(object):' | |||||
295 | if "," in username: |
|
302 | if "," in username: | |
296 | raise LdapUsernameError( |
|
303 | raise LdapUsernameError( | |
297 | "invalid character `,` in username: `{}`".format(username)) |
|
304 | "invalid character `,` in username: `{}`".format(username)) | |
|
305 | ldap_conn = None | |||
298 | try: |
|
306 | try: | |
299 |
|
|
307 | ldap_conn = self._get_ldap_conn() | |
300 | filter_ = '(&%s(%s=%s))' % ( |
|
308 | filter_ = '(&%s(%s=%s))' % ( | |
301 | self.LDAP_FILTER, self.attr_login, username) |
|
309 | self.LDAP_FILTER, self.attr_login, username) | |
302 | log.debug("Authenticating %r filter %s at %s", self.BASE_DN, |
|
310 | log.debug("Authenticating %r filter %s at %s", self.BASE_DN, | |
303 | filter_, self.LDAP_SERVER) |
|
311 | filter_, self.LDAP_SERVER) | |
304 |
lobjects = |
|
312 | lobjects = ldap_conn.search_ext_s( | |
305 | self.BASE_DN, self.SEARCH_SCOPE, filter_) |
|
313 | self.BASE_DN, self.SEARCH_SCOPE, filter_) | |
306 |
|
314 | |||
307 | if not lobjects: |
|
315 | if not lobjects: | |
@@ -315,7 +323,7 b' class AuthLdap(object):' | |||||
315 | continue |
|
323 | continue | |
316 |
|
324 | |||
317 | user_attrs = self.fetch_attrs_from_simple_bind( |
|
325 | user_attrs = self.fetch_attrs_from_simple_bind( | |
318 |
|
|
326 | ldap_conn, dn, username, password) | |
319 | if user_attrs: |
|
327 | if user_attrs: | |
320 | break |
|
328 | break | |
321 |
|
329 | |||
@@ -333,6 +341,15 b' class AuthLdap(object):' | |||||
333 | raise LdapConnectionError( |
|
341 | raise LdapConnectionError( | |
334 | "LDAP can't access authentication " |
|
342 | "LDAP can't access authentication " | |
335 | "server, org_exc:%s" % org_exc) |
|
343 | "server, org_exc:%s" % org_exc) | |
|
344 | finally: | |||
|
345 | if ldap_conn: | |||
|
346 | log.debug('ldap: connection release') | |||
|
347 | try: | |||
|
348 | ldap_conn.unbind_s() | |||
|
349 | except Exception: | |||
|
350 | # for any reason this can raise exception we must catch it | |||
|
351 | # to not crush the server | |||
|
352 | pass | |||
336 |
|
353 | |||
337 | return dn, user_attrs |
|
354 | return dn, user_attrs | |
338 |
|
355 |
General Comments 0
You need to be logged in to leave comments.
Login now