Example #1
0
    def create_connection(authtype=None,
                          server=None,
                          user=None,
                          password=None,
                          auto_bind=False,
                          client_strategy=ldap3.SYNC,
                          check_names=True,
                          auto_referrals=False):

        authentication = None
        if not user:
            authentication = ldap3.ANONYMOUS

        if authtype == AUTHTYPE.SIMPLE:
            if not authentication:
                authentication = ldap3.SIMPLE
            l = ldap3.Connection(server,
                                 user=user,
                                 password=to_utf8(password),
                                 auto_bind=auto_bind,
                                 client_strategy=client_strategy,
                                 authentication=authentication,
                                 check_names=check_names,
                                 auto_referrals=auto_referrals)
        elif authtype == AUTHTYPE.NTLM:  # pragma: no cover
            if not authentication:
                authentication = ldap3.NTLM
            l = ldap3.Connection(server,
                                 user=user,
                                 password=to_utf8(password),
                                 auto_bind=auto_bind,
                                 client_strategy=client_strategy,
                                 authentication=authentication,
                                 check_names=check_names,
                                 auto_referrals=auto_referrals)
        elif authtype == AUTHTYPE.SASL_DIGEST_MD5:  # pragma: no cover
            if not authentication:
                authentication = ldap3.SASL
            sasl_credentials = (str(user), str(password))
            l = ldap3.Connection(server,
                                 sasl_mechanism="DIGEST-MD5",
                                 sasl_credentials=sasl_credentials,
                                 auto_bind=auto_bind,
                                 client_strategy=client_strategy,
                                 authentication=authentication,
                                 check_names=check_names,
                                 auto_referrals=auto_referrals)
        else:
            raise Exception("Authtype {0!s} not supported".format(authtype))

        return l
Example #2
0
    def create_connection(authtype=None, server=None, user=None,
                          password=None, auto_bind=False,
                          client_strategy=ldap3.SYNC,
                          check_names=True,
                          auto_referrals=False):

        authentication = None
        if not user:
            authentication = ldap3.ANONYMOUS

        if authtype == AUTHTYPE.SIMPLE:
            if not authentication:
                authentication = ldap3.SIMPLE
            l = ldap3.Connection(server,
                                 user=user,
                                 password=to_utf8(password),
                                 auto_bind=auto_bind,
                                 client_strategy=client_strategy,
                                 authentication=authentication,
                                 check_names=check_names,
                                 auto_referrals=auto_referrals)
        elif authtype == AUTHTYPE.NTLM:  # pragma: no cover
            if not authentication:
                authentication = ldap3.NTLM
            l = ldap3.Connection(server,
                                 user=user,
                                 password=to_utf8(password),
                                 auto_bind=auto_bind,
                                 client_strategy=client_strategy,
                                 authentication=authentication,
                                 check_names=check_names,
                                 auto_referrals=auto_referrals)
        elif authtype == AUTHTYPE.SASL_DIGEST_MD5:  # pragma: no cover
            if not authentication:
                authentication = ldap3.SASL
            sasl_credentials = (str(user), str(password))
            l = ldap3.Connection(server,
                                 sasl_mechanism="DIGEST-MD5",
                                 sasl_credentials=sasl_credentials,
                                 auto_bind=auto_bind,
                                 client_strategy=client_strategy,
                                 authentication=authentication,
                                 check_names=check_names,
                                 auto_referrals=auto_referrals)
        else:
            raise Exception("Authtype {0!s} not supported".format(authtype))

        return l
Example #3
0
def derive_key(xml, password):
    """
    Derive the encryption key from the password with the parameters given
    in the XML soup.

    :param xml: The XML
    :param password: the password
    :return: The derived key, hexlified
    """
    if not password:
        raise ImportException("The XML KeyContainer specifies a derived "
                              "encryption key, but no password given!")

    keymeth = xml.keycontainer.encryptionkey.derivedkey.keyderivationmethod
    derivation_algo = keymeth["algorithm"].split("#")[-1]
    if derivation_algo.lower() != "pbkdf2":
        raise ImportException("We only support PBKDF2 as Key derivation "
                              "function!")
    salt = keymeth.find("salt").text.strip()
    keylength = keymeth.find("keylength").text.strip()
    rounds = keymeth.find("iterationcount").text.strip()
    r = pbkdf2_hmac('sha1',
                    to_utf8(password),
                    base64.b64decode(salt),
                    rounds=int(rounds),
                    keylen=int(keylength))
    return binascii.hexlify(r)
Example #4
0
def encryptPassword(password):
    from privacyidea.lib.utils import to_utf8
    hsm = _get_hsm()
    try:
        ret = hsm.encrypt_password(to_utf8(password))
    except Exception as exx:  # pragma: no cover
        log.warning(exx)
        ret = "FAILED TO ENCRYPT PASSWORD!"
    return ret
Example #5
0
def encryptPassword(password):
    from privacyidea.lib.utils import to_utf8
    hsm = _get_hsm()
    try:
        ret = hsm.encrypt_password(to_utf8(password))
    except Exception as exx:  # pragma: no cover
        log.warning(exx)
        ret = "FAILED TO ENCRYPT PASSWORD!"
    return ret
Example #6
0
    def checkPass(self, uid, password):
        """
        This function checks the password for a given uid.
        - returns true in case of success
        -         false if password does not match

        """
        if self.authtype == AUTHTYPE.NTLM:  # pragma: no cover
            # fetch the PreWindows 2000 Domain from the self.binddn
            # which would be of the format DOMAIN\username and compose the
            # bind_user to DOMAIN\sAMAcountName
            domain_name = self.binddn.split('\\')[0]
            uinfo = self.getUserInfo(uid)
            # In fact we need the sAMAccountName. If the username mapping is
            # another attribute than the sAMAccountName the authentication
            # will fail!
            bind_user = "******".format(domain_name,
                                             uinfo.get("username"))
        else:
            bind_user = self._getDN(uid)

        server_pool = self.get_serverpool(self.uri,
                                          self.timeout,
                                          get_info=ldap3.NONE,
                                          tls_context=self.tls_context)
        password = to_utf8(password)

        try:
            log.debug("Authtype: {0!r}".format(self.authtype))
            log.debug("user    : {0!r}".format(bind_user))
            # Whatever happens. If we have an empty bind_user, we must break
            # since we must avoid anonymous binds!
            if not bind_user or len(bind_user) < 1:
                raise Exception("No valid user. Empty bind_user.")
            l = self.create_connection(authtype=self.authtype,
                                       server=server_pool,
                                       user=bind_user,
                                       password=password,
                                       receive_timeout=self.timeout,
                                       auto_referrals=not self.noreferrals)
            l.open()
            r = l.bind()
            log.debug("bind result: {0!r}".format(r))
            if not r:
                raise Exception("Wrong credentials")
            log.debug("bind seems successful.")
            l.unbind()
            log.debug("unbind successful.")
        except Exception as e:
            log.warning(
                "failed to check password for {0!r}/{1!r}: {2!r}".format(
                    uid, bind_user, e))
            log.debug(traceback.format_exc())
            return False

        return True
Example #7
0
    def test_25_encodings(self):
        u = u'Hello Wörld'
        b = b'Hello World'
        self.assertEquals(to_utf8(None), None)
        self.assertEquals(to_utf8(u), u.encode('utf8'))
        self.assertEquals(to_utf8(b), b)

        self.assertEquals(to_unicode(u), u)
        self.assertEquals(to_unicode(b), b.decode('utf8'))
        self.assertEquals(to_unicode(None), None)
        self.assertEquals(to_unicode(10), 10)

        self.assertEquals(to_bytes(u), u.encode('utf8'))
        self.assertEquals(to_bytes(b), b)
        self.assertEquals(to_bytes(10), 10)

        self.assertEquals(to_byte_string(u), u.encode('utf8'))
        self.assertEquals(to_byte_string(b), b)
        self.assertEquals(to_byte_string(10), b'10')
    def test_25_encodings(self):
        u = u'Hello Wörld'
        b = b'Hello World'
        self.assertEquals(to_utf8(None), None)
        self.assertEquals(to_utf8(u), u.encode('utf8'))
        self.assertEquals(to_utf8(b), b)

        self.assertEquals(to_unicode(u), u)
        self.assertEquals(to_unicode(b), b.decode('utf8'))
        self.assertEquals(to_unicode(None), None)
        self.assertEquals(to_unicode(10), 10)

        self.assertEquals(to_bytes(u), u.encode('utf8'))
        self.assertEquals(to_bytes(b), b)
        self.assertEquals(to_bytes(10), 10)

        self.assertEquals(to_byte_string(u), u.encode('utf8'))
        self.assertEquals(to_byte_string(b), b)
        self.assertEquals(to_byte_string(10), b'10')
Example #9
0
 def getResolverId(self):
     """
     Returns the resolver Id
     This should be an Identifier of the resolver, preferable the type
     and the name of the resolver.
     """
     # Take the following parts, join them with the NULL byte and return
     # the hexlified SHA-1 digest
     id_parts = (to_utf8(self.connect_string), str(self.pool_size),
                 str(self.pool_recycle), str(self.pool_timeout))
     resolver_id = binascii.hexlify(
         hashlib.sha1("\x00".join(id_parts)).digest())
     return "sql." + resolver_id
Example #10
0
 def getResolverId(self):
     """
     Returns the resolver Id
     This should be an Identifier of the resolver, preferable the type
     and the name of the resolver.
     """
     # Take the following parts, join them with the NULL byte and return
     # the hexlified SHA-1 digest
     id_parts = (to_utf8(self.connect_string),
                 str(self.pool_size),
                 str(self.pool_recycle),
                 str(self.pool_timeout))
     resolver_id = binascii.hexlify(hashlib.sha1("\x00".join(id_parts)).digest())
     return "sql." + resolver_id
Example #11
0
    def checkPass(self, uid, password):
        """
        This function checks the password for a given uid.
        - returns true in case of success
        -         false if password does not match
        
        """
        if self.authtype == AUTHTYPE.NTLM:  # pragma: no cover
            # fetch the PreWindows 2000 Domain from the self.binddn
            # which would be of the format DOMAIN\username and compose the
            # bind_user to DOMAIN\sAMAcountName
            domain_name = self.binddn.split('\\')[0]
            uinfo = self.getUserInfo(uid)
            # In fact we need the sAMAccountName. If the username mapping is
            # another attribute than the sAMAccountName the authentication
            # will fail!
            bind_user = "******" % (domain_name, uinfo.get("username"))
        else:
            bind_user = self._getDN(uid)

        server_pool = self.get_serverpool(self.uri, self.timeout)
        password = to_utf8(password)

        try:
            log.debug("Authtype: %s" % self.authtype)
            log.debug("user    : %s" % bind_user)
            # Whatever happens. If we have an empty bind_user, we must break
            # since we must avoid anonymous binds!
            if not bind_user or len(bind_user) < 1:
                raise Exception("No valid user. Empty bind_user.")
            l = self.create_connection(authtype=self.authtype,
                                       server=server_pool,
                                       user=bind_user,
                                       password=password,
                                       auto_referrals=not self.noreferrals)
            l.open()
            r = l.bind()
            log.debug("bind result: %s" % r)
            if not r:
                raise Exception("Wrong credentials")
            log.debug("bind seems successful.")
            l.unbind()
            log.debug("unbind successful.")
        except Exception as e:
            log.warning("failed to check password for %r/%r: %r"
                        % (uid, bind_user, e))
            return False
        
        return True
Example #12
0
def derive_key(xml, password):
    """
    Derive the encryption key from the password with the parameters given
    in the XML soup.

    :param xml: The XML
    :param password: the password
    :return: The derived key, hexlified
    """
    if not password:
        raise ImportException("The XML KeyContainer specifies a derived " "encryption key, but no password given!")

    keymeth = xml.keycontainer.encryptionkey.derivedkey.keyderivationmethod
    derivation_algo = keymeth["algorithm"].split("#")[-1]
    if derivation_algo.lower() != "pbkdf2":
        raise ImportException("We only support PBKDF2 as Key derivation " "function!")
    salt = keymeth.find("salt").text.strip()
    keylength = keymeth.find("keylength").text.strip()
    rounds = keymeth.find("iterationcount").text.strip()
    r = pbkdf2(to_utf8(password), base64.b64decode(salt), int(rounds), int(keylength))
    return binascii.hexlify(r)
Example #13
0
    def getUserInfo(self, userId):
        """
        This function returns all user info for a given userid/object.

        :param userId: The userid of the object
        :type userId: string
        :return: A dictionary with the keys defined in self.userinfo
        :rtype: dict
        """
        ret = {}
        self._bind()

        if self.uidtype.lower() == "dn":
            # encode utf8, so that also german ulauts work in the DN
            self.l.search(search_base=to_utf8(userId),
                          search_scope=self.scope,
                          search_filter="(&" + self.searchfilter + ")",
                          attributes=self.userinfo.values())
        else:
            if self.uidtype == "objectGUID":
                userId = uuid.UUID("{{{0!s}}}".format(userId)).bytes_le
                userId = escape_bytes(userId)
            filter = "(&{0!s}({1!s}={2!s}))".format(self.searchfilter,
                                                    self.uidtype, userId)
            self.l.search(search_base=self.basedn,
                          search_scope=self.scope,
                          search_filter=filter,
                          attributes=self.userinfo.values())

        r = self.l.response
        r = self._trim_result(r)
        if len(r) > 1:  # pragma: no cover
            raise Exception(
                "Found more than one object for uid {0!r}".format(userId))

        for entry in r:
            attributes = entry.get("attributes")
            ret = self._ldap_attributes_to_user_object(attributes)

        return ret
Example #14
0
    def getUserInfo(self, userId):
        """
        This function returns all user info for a given userid/object.

        :param userId: The userid of the object
        :type userId: string
        :return: A dictionary with the keys defined in self.userinfo
        :rtype: dict
        """
        ret = {}
        self._bind()

        if self.uidtype.lower() == "dn":
            # encode utf8, so that also german ulauts work in the DN
            self.l.search(search_base=to_utf8(userId),
                          search_scope=self.scope,
                          search_filter="(&" + self.searchfilter + ")",
                          attributes=self.userinfo.values())
        else:
            if self.uidtype == "objectGUID":
                userId = uuid.UUID("{{{0!s}}}".format(userId)).bytes_le
                userId = escape_bytes(userId)
            filter = "(&{0!s}({1!s}={2!s}))".format(self.searchfilter, self.uidtype, userId)
            self.l.search(search_base=self.basedn,
                              search_scope=self.scope,
                              search_filter=filter,
                              attributes=self.userinfo.values())

        r = self.l.response
        r = self._trim_result(r)
        if len(r) > 1:  # pragma: no cover
            raise Exception("Found more than one object for uid {0!r}".format(userId))

        for entry in r:
            attributes = entry.get("attributes")
            ret = self._ldap_attributes_to_user_object(attributes)

        return ret
Example #15
0
    def testconnection(cls, param):
        """
        This function lets you test the to be saved LDAP connection.

        This is taken from controllers/admin.py

        :param param: A dictionary with all necessary parameter to test
                        the connection.
        :type param: dict

        :return: Tuple of success and a description
        :rtype: (bool, string)

        Parameters are:
            BINDDN, BINDPW, LDAPURI, TIMEOUT, LDAPBASE, LOGINNAMEATTRIBUTE,
            LDAPSEARCHFILTER,
            LDAPFILTER, USERINFO, SIZELIMIT, NOREFERRALS, CACERTIFICATE,
            AUTHTYPE
        """
        success = False
        uidtype = param.get("UIDTYPE")
        try:
            server_pool = cls.get_serverpool(param.get("LDAPURI"),
                                             float(param.get("TIMEOUT", 5)))
            l = cls.create_connection(authtype=param.get("AUTHTYPE",
                                                          AUTHTYPE.SIMPLE),
                                      server=server_pool,
                                      user=param.get("BINDDN"),
                                      password=to_utf8(param.get("BINDPW")),
                                      auto_referrals=not param.get(
                                           "NOREFERRALS"))
            l.open()
            #log.error("LDAP Server Pool States: %s" % server_pool.pool_states)
            if not l.bind():
                raise Exception("Wrong credentials")
            # create searchattributes
            attributes = yaml.load(param["USERINFO"]).values()
            if uidtype.lower() != "dn":
                attributes.append(str(uidtype))
            # search for users...
            g = l.extend.standard.paged_search(
                search_base=param["LDAPBASE"],
                search_filter="(&" + param["LDAPSEARCHFILTER"] + ")",
                search_scope=param.get("SCOPE") or ldap3.SUBTREE,
                attributes=attributes,
                paged_size=100,
                generator=True)
            # returns a generator of dictionaries
            count = 0
            uidtype_count = 0
            for entry in g:
                try:
                    userid = cls._get_uid(entry, uidtype)
                    count += 1
                    if userid:
                        uidtype_count += 1
                except Exception as exx:  # pragma: no cover
                    log.warning("Error during fetching LDAP objects:"
                                " {0!r}".format(exx))
                    log.debug("{0!s}".format(traceback.format_exc()))

            if uidtype_count < count:  # pragma: no cover
                desc = _("Your LDAP config found %i user objects, but only %i "
                         "with the specified uidtype" % (count, uidtype_count))
            else:
                desc = _("Your LDAP config seems to be OK, %i user objects "
                         "found.") % count

            l.unbind()
            success = True

        except Exception as e:
            desc = "{0!r}".format(e)

        return success, desc
Example #16
0
    def create_connection(authtype=None, server=None, user=None,
                          password=None, auto_bind=False,
                          client_strategy=ldap3.SYNC,
                          check_names=True,
                          auto_referrals=False,
                          receive_timeout=5):
        """
        Create a connection to the LDAP server.

        :param authtype:
        :param server:
        :param user:
        :param password:
        :param auto_bind:
        :param client_strategy:
        :param check_names:
        :param auto_referrals:
        :param receive_timeout: At the moment we do not use this,
            since receive_timeout is not supported by ldap3 < 2.
        :return:
        """

        authentication = None
        if not user:
            authentication = ldap3.ANONYMOUS

        if authtype == AUTHTYPE.SIMPLE:
            if not authentication:
                authentication = ldap3.SIMPLE
            l = ldap3.Connection(server, user=user,
                                 password=to_utf8(password),
                                 auto_bind=auto_bind,
                                 client_strategy=client_strategy,
                                 authentication=authentication,
                                 check_names=check_names,
                                 # receive_timeout=receive_timeout,
                                 auto_referrals=auto_referrals)
        elif authtype == AUTHTYPE.NTLM:  # pragma: no cover
            if not authentication:
                authentication = ldap3.NTLM
            l = ldap3.Connection(server,
                                 user=user,
                                 password=to_utf8(password),
                                 auto_bind=auto_bind,
                                 client_strategy=client_strategy,
                                 authentication=authentication,
                                 check_names=check_names,
                                 # receive_timeout=receive_timeout,
                                 auto_referrals=auto_referrals)
        elif authtype == AUTHTYPE.SASL_DIGEST_MD5:  # pragma: no cover
            if not authentication:
                authentication = ldap3.SASL
            sasl_credentials = (str(user), str(password))
            l = ldap3.Connection(server,
                                 sasl_mechanism="DIGEST-MD5",
                                 sasl_credentials=sasl_credentials,
                                 auto_bind=auto_bind,
                                 client_strategy=client_strategy,
                                 authentication=authentication,
                                 check_names=check_names,
                                 # receive_timeout=receive_timeout,
                                 auto_referrals=auto_referrals)
        else:
            raise Exception("Authtype {0!s} not supported".format(authtype))

        return l
Example #17
0
    def testconnection(cls, param):
        """
        This function lets you test the to be saved LDAP connection.
        
        This is taken from controllers/admin.py
        
        :param param: A dictionary with all necessary parameter to test
                        the connection.
        :type param: dict
        
        :return: Tuple of success and a description
        :rtype: (bool, string)
        
        Parameters are:
            BINDDN, BINDPW, LDAPURI, TIMEOUT, LDAPBASE, LOGINNAMEATTRIBUTE,
            LDAPSEARCHFILTER,
            LDAPFILTER, USERINFO, SIZELIMIT, NOREFERRALS, CACERTIFICATE,
            AUTHTYPE
        """
        success = False
        uidtype = param.get("UIDTYPE")
        try:
            server_pool = cls.get_serverpool(param.get("LDAPURI"),
                                             float(param.get("TIMEOUT", 5)))
            l = cls.create_connection(
                authtype=param.get("AUTHTYPE", AUTHTYPE.SIMPLE),
                server=server_pool,
                user=param.get("BINDDN"),
                password=to_utf8(param.get("BINDPW")),
                auto_referrals=not param.get("NOREFERRALS"))
            l.open()
            #log.error("LDAP Server Pool States: %s" % server_pool.pool_states)
            if not l.bind():
                raise Exception("Wrong credentials")
            # create searchattributes
            attributes = yaml.load(param["USERINFO"]).values()
            if uidtype.lower() != "dn":
                attributes.append(str(uidtype))
            # search for users...
            l.search(search_base=param["LDAPBASE"],
                     search_scope=param.get("SCOPE") or ldap3.SUBTREE,
                     search_filter="(&" + param["LDAPSEARCHFILTER"] + ")",
                     attributes=attributes)

            r = l.response
            count = len(r)
            uidtype_count = 0
            for entry in r:
                userid = cls._get_uid(entry, uidtype)
                if userid:
                    uidtype_count += 1
            if uidtype_count < count:  # pragma: no cover
                desc = _("Your LDAP config found %i user objects, but only %i "
                         "with the specified uidtype" % (count, uidtype_count))
            else:
                desc = _("Your LDAP config seems to be OK, %i user objects found.")\
                    % count

            l.unbind()
            success = True

        except Exception as e:
            desc = "%r" % e

        return success, desc
Example #18
0
    def create_connection(authtype=None, server=None, user=None,
                          password=None, auto_bind=False,
                          client_strategy=ldap3.SYNC,
                          check_names=True,
                          auto_referrals=False,
                          receive_timeout=5,
                          start_tls=False):
        """
        Create a connection to the LDAP server.

        :param authtype:
        :param server:
        :param user:
        :param password:
        :param auto_bind:
        :param client_strategy:
        :param check_names:
        :param auto_referrals:
        :param receive_timeout: At the moment we do not use this,
            since receive_timeout is not supported by ldap3 < 2.
        :return:
        """

        authentication = None
        if not user:
            authentication = ldap3.ANONYMOUS

        if authtype == AUTHTYPE.SIMPLE:
            if not authentication:
                authentication = ldap3.SIMPLE
            # SIMPLE works with passwords as UTF8 and unicode
            l = ldap3.Connection(server, user=user,
                                 password=password,
                                 auto_bind=auto_bind,
                                 client_strategy=client_strategy,
                                 authentication=authentication,
                                 check_names=check_names,
                                 # receive_timeout=receive_timeout,
                                 auto_referrals=auto_referrals)
        elif authtype == AUTHTYPE.NTLM:  # pragma: no cover
            if not authentication:
                authentication = ldap3.NTLM
            # NTLM requires the password to be unicode
            l = ldap3.Connection(server,
                                 user=user,
                                 password=password,
                                 auto_bind=auto_bind,
                                 client_strategy=client_strategy,
                                 authentication=authentication,
                                 check_names=check_names,
                                 # receive_timeout=receive_timeout,
                                 auto_referrals=auto_referrals)
        elif authtype == AUTHTYPE.SASL_DIGEST_MD5:  # pragma: no cover
            if not authentication:
                authentication = ldap3.SASL
            password = to_utf8(password)
            sasl_credentials = (str(user), str(password))
            l = ldap3.Connection(server,
                                 sasl_mechanism="DIGEST-MD5",
                                 sasl_credentials=sasl_credentials,
                                 auto_bind=auto_bind,
                                 client_strategy=client_strategy,
                                 authentication=authentication,
                                 check_names=check_names,
                                 # receive_timeout=receive_timeout,
                                 auto_referrals=auto_referrals)
        else:
            raise Exception("Authtype {0!s} not supported".format(authtype))

        if start_tls:
            l.open(read_server_info=False)
            log.debug("Doing start_tls")
            r = l.start_tls(read_server_info=False)

        return l
Example #19
0
    def testconnection(cls, param):
        """
        This function lets you test the to be saved LDAP connection.

        This is taken from controllers/admin.py

        :param param: A dictionary with all necessary parameter to test
                        the connection.
        :type param: dict

        :return: Tuple of success and a description
        :rtype: (bool, string)

        Parameters are:
            BINDDN, BINDPW, LDAPURI, TIMEOUT, LDAPBASE, LOGINNAMEATTRIBUTE,
            LDAPSEARCHFILTER,
            LDAPFILTER, USERINFO, SIZELIMIT, NOREFERRALS, CACERTIFICATE,
            AUTHTYPE
        """
        success = False
        uidtype = param.get("UIDTYPE")
        timeout = float(param.get("TIMEOUT", 5))
        try:
            server_pool = cls.get_serverpool(param.get("LDAPURI"),
                                             timeout)
            l = cls.create_connection(authtype=param.get("AUTHTYPE",
                                                          AUTHTYPE.SIMPLE),
                                      server=server_pool,
                                      user=param.get("BINDDN"),
                                      password=to_utf8(param.get("BINDPW")),
                                      receive_timeout=timeout,
                                      auto_referrals=not param.get(
                                           "NOREFERRALS"))
            l.open()
            #log.error("LDAP Server Pool States: %s" % server_pool.pool_states)
            if not l.bind():
                raise Exception("Wrong credentials")
            # create searchattributes
            attributes = yaml.load(param["USERINFO"]).values()
            if uidtype.lower() != "dn":
                attributes.append(str(uidtype))
            # search for users...
            g = l.extend.standard.paged_search(
                search_base=param["LDAPBASE"],
                search_filter="(&" + param["LDAPSEARCHFILTER"] + ")",
                search_scope=param.get("SCOPE") or ldap3.SUBTREE,
                attributes=attributes,
                paged_size=100,
                generator=True)
            # returns a generator of dictionaries
            count = 0
            uidtype_count = 0
            for entry in g:
                try:
                    userid = cls._get_uid(entry, uidtype)
                    count += 1
                    if userid:
                        uidtype_count += 1
                except Exception as exx:  # pragma: no cover
                    log.warning("Error during fetching LDAP objects:"
                                " {0!r}".format(exx))
                    log.debug("{0!s}".format(traceback.format_exc()))

            if uidtype_count < count:  # pragma: no cover
                desc = _("Your LDAP config found %i user objects, but only %i "
                         "with the specified uidtype" % (count, uidtype_count))
            else:
                desc = _("Your LDAP config seems to be OK, %i user objects "
                         "found.") % count

            l.unbind()
            success = True

        except Exception as e:
            desc = "{0!r}".format(e)

        return success, desc