14 |
14 |
# You should have received a copy of the GNU Affero General Public License
|
15 |
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16 |
16 |
|
|
17 |
import hashlib
|
|
18 |
|
17 |
19 |
try:
|
18 |
20 |
import ldap
|
19 |
21 |
import ldap.modlist
|
... | ... | |
35 |
37 |
# code originaly copied from by now merely inspired by
|
36 |
38 |
# http://www.amherst.k12.oh.us/django-ldap.html
|
37 |
39 |
|
|
40 |
from django.core.cache import cache
|
38 |
41 |
from django.core.exceptions import ImproperlyConfigured
|
39 |
42 |
from django.conf import settings
|
40 |
43 |
from django.contrib.auth import get_user_model
|
... | ... | |
70 |
73 |
'/var/lib/ca-certificates/ca-bundle.pem', # OpenSuse
|
71 |
74 |
]
|
72 |
75 |
|
|
76 |
|
73 |
77 |
# Select a system certificate store
|
74 |
78 |
for bundle_path in CA_BUNDLE_PATHS:
|
75 |
79 |
if os.path.exists(bundle_path):
|
... | ... | |
327 |
331 |
|
328 |
332 |
def check_password(self, raw_password):
|
329 |
333 |
connection = self.ldap_backend.get_connection(self.block)
|
330 |
|
try:
|
331 |
|
connection.simple_bind_s(self.dn, raw_password)
|
332 |
|
except ldap.INVALID_CREDENTIALS:
|
333 |
|
return False
|
334 |
|
except ldap.LDAPError as e:
|
335 |
|
log.error('LDAPUser.check_password() failed: %r', e)
|
336 |
|
return False
|
337 |
|
self._current_password = raw_password
|
338 |
|
return True
|
|
334 |
if connection:
|
|
335 |
try:
|
|
336 |
connection.simple_bind_s(self.dn, raw_password)
|
|
337 |
self._current_password = raw_password
|
|
338 |
return True
|
|
339 |
except ldap.INVALID_CREDENTIALS:
|
|
340 |
return False
|
|
341 |
except ldap.LDAPError as e:
|
|
342 |
log.warning('ldap: check_password failed, %r', e)
|
|
343 |
log.warning('ldap: check_password failed, could not get a connection')
|
|
344 |
return False
|
339 |
345 |
|
340 |
346 |
def set_password(self, new_password):
|
341 |
347 |
# Allow change password to work in all cases, as the form does a check_password() first
|
... | ... | |
343 |
349 |
_current_password = getattr(self, '_current_password', None) or self.get_password_in_session()
|
344 |
350 |
if _current_password != new_password:
|
345 |
351 |
conn = self.get_connection()
|
|
352 |
if not conn:
|
|
353 |
log.warning('ldap: set_password failed, could not get a connection')
|
|
354 |
return
|
346 |
355 |
self.ldap_backend.modify_password(conn, self.block, self.dn, _current_password, new_password)
|
347 |
356 |
self._current_password = new_password
|
348 |
357 |
self.keep_password_in_session(new_password)
|
... | ... | |
365 |
374 |
self.ldap_backend.update_default(self.block, validate=False)
|
366 |
375 |
return self.ldap_backend.get_connection(self.block, credentials=credentials)
|
367 |
376 |
|
368 |
|
def get_attributes(self):
|
|
377 |
def get_attributes(self, attribute_source, ctx):
|
|
378 |
cache_key = hashlib.md5((force_text(str(self.pk)) + ';' + force_text(self.dn)).encode('utf-8')).hexdigest()
|
369 |
379 |
conn = self.get_connection()
|
370 |
|
return self.ldap_backend.get_ldap_attributes(self.block, conn, self.dn) or {}
|
|
380 |
# prevents blocking on temporary LDAP failures
|
|
381 |
if conn is not None:
|
|
382 |
attributes = self.ldap_backend.get_ldap_attributes(self.block, conn, self.dn) or {}
|
|
383 |
# keep attributes in cache for 8 hours
|
|
384 |
cache.set(cache_key, attributes, 3600 * 8)
|
|
385 |
return attributes
|
|
386 |
else:
|
|
387 |
log.warning('ldap: get_attributes failed, could not get a connection')
|
|
388 |
return cache.get(cache_key, {})
|
371 |
389 |
|
372 |
390 |
def save(self, *args, **kwargs):
|
373 |
391 |
if hasattr(self, 'keep_pk'):
|
... | ... | |
1284 |
1302 |
'''Try to get at least one connection'''
|
1285 |
1303 |
for conn in cls.get_connections(block, credentials=credentials):
|
1286 |
1304 |
return conn
|
1287 |
|
log.error('could not get a connection')
|
|
1305 |
return None
|
1288 |
1306 |
|
1289 |
1307 |
@classmethod
|
1290 |
1308 |
def update_default(cls, block, validate=True):
|
... | ... | |
1387 |
1405 |
continue
|
1388 |
1406 |
for external_id_tuple in map_text(block['external_id_tuples']):
|
1389 |
1407 |
conn = self.ldap_backend.get_connection(block)
|
|
1408 |
if not conn:
|
|
1409 |
log.warning('ldap: password-lost authenticate failed, could not get a connection')
|
|
1410 |
continue
|
1390 |
1411 |
try:
|
1391 |
1412 |
if external_id_tuple == ('dn:noquote',):
|
1392 |
1413 |
dn = external_id
|