ldap.py 2.64 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Copyright (c) 2016, Daniele Venzano
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
15 16 17

"""LDAP authentication module."""

18 19
import logging

20 21
try:
    import ldap
22
    import ldap.sasl
23 24 25 26 27
except ImportError:
    ldap = None
    LDAP_AVAILABLE = False
else:
    LDAP_AVAILABLE = True
28

29
import zoe_api.auth.base
30 31
import zoe_api.exceptions

32
from zoe_lib.config import get_conf
33 34 35 36

log = logging.getLogger(__name__)


37
class LDAPAuthenticator:
38
    """A simple LDAP authenticator."""
39

40 41 42
    def __init__(self, conf, sasl):
        self.connection = ldap.initialize(conf.ldap_server_uri)
        self.base_dn = conf.ldap_base_dn
43 44 45 46
        self.sasl = sasl
        self.connection.protocol_version = ldap.VERSION3
        if self.sasl:
            self.sasl_auth = ldap.sasl.sasl({}, 'GSSAPI')
47 48

    def auth(self, username, password):
49
        """Authenticate the user or raise an exception."""
50 51
        search_filter = "uid=" + username
        try:
52 53 54 55 56 57 58 59 60
            if self.sasl:
                self.connection.sasl_interactive_bind_s('', self.sasl_auth)
            else:
                self.connection.bind_s(get_conf().ldap_bind_user, get_conf().ldap_bind_password)
        except ldap.LDAPError:
            log.error('Unknown LDAP BIND user or wrong password.')
            raise zoe_api.exceptions.ZoeAuthException('Unknown LDAP BIND user or wrong password.')

        try:
61
            result = self.connection.search_s(self.base_dn, ldap.SCOPE_SUBTREE, search_filter)
62 63
            if len(result) == 0:
                raise zoe_api.exceptions.ZoeAuthException('Unknown user or wrong password.')
64 65 66
            result = self.connection.compare_s(search_filter + ',' + self.base_dn, 'userPassword', password)
            if result == 0:
                raise zoe_api.exceptions.ZoeAuthException('Unknown user or wrong password.')
67 68 69 70 71 72
        except ldap.LDAPError as ex:
            if ex.args[0]['desc'] == 'Invalid credentials':
                raise zoe_api.exceptions.ZoeAuthException('Unknown user or wrong password.')
            else:
                log.exception("LDAP exception")
                zoe_api.exceptions.ZoeAuthException('LDAP error.')
73 74
        finally:
            self.connection.unbind_s()
75
        return True