Use sane default settings for ldap connections

LDAP connections no longer depend on sane settings in global ldap.conf
and use good default settings for cert validation, CA, and SASL canonization.

https://pagure.io/freeipa/issue/7418

Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
This commit is contained in:
Christian Heimes 2018-02-21 14:35:25 +01:00
parent 9b8bb85eca
commit 9a9c8ced30
3 changed files with 30 additions and 24 deletions

View File

@ -1572,7 +1572,7 @@ def cert_summary(msg, certs, indent=' '):
def get_certs_from_ldap(server, base_dn, realm, ca_enabled):
ldap_uri = ipaldap.get_ldap_uri(server)
conn = ipaldap.LDAPClient(ldap_uri, sasl_nocanon=True)
conn = ipaldap.LDAPClient(ldap_uri)
try:
conn.gssapi_bind()
certs = certstore.get_ca_certs(conn, base_dn, realm, ca_enabled)

View File

@ -20,6 +20,7 @@
#
import binascii
import errno
import logging
import time
import datetime
@ -87,27 +88,33 @@ if six.PY2 and hasattr(ldap, 'LDAPBytesWarning'):
def ldap_initialize(uri, cacertfile=None):
"""Wrapper around ldap.initialize()
The function undoes global and local ldap.conf settings that may cause
issues or reduce security:
* Canonization of SASL host names is disabled.
* With cacertfile=None, the connection uses OpenSSL's default verify
locations, also known as system-wide trust store.
* Cert validation is enforced.
* SSLv2 and SSLv3 are disabled.
"""
conn = ldap.initialize(uri)
# Do not perform reverse DNS lookups to canonicalize SASL host names
conn.set_option(ldap.OPT_X_SASL_NOCANON, ldap.OPT_ON)
if not uri.startswith('ldapi://'):
if cacertfile:
if not os.path.isfile(cacertfile):
raise IOError(errno.ENOENT, cacertfile)
conn.set_option(ldap.OPT_X_TLS_CACERTFILE, cacertfile)
newctx = True
else:
newctx = False
req_cert = conn.get_option(ldap.OPT_X_TLS_REQUIRE_CERT)
if req_cert != ldap.OPT_X_TLS_DEMAND:
# SSLv3 and SSLv2 are insecure
conn.set_option(ldap.OPT_X_TLS_PROTOCOL_MIN, 0x301) # TLS 1.0
# libldap defaults to cert validation, but the default can be
# overridden in global or user local ldap.conf.
conn.set_option(
ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND
)
newctx = True
# reinitialize TLS context
if newctx:
conn.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)
# reinitialize TLS context to materialize settings
conn.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
return conn
@ -733,7 +740,7 @@ class LDAPClient(object):
def __init__(self, ldap_uri, start_tls=False, force_schema_updates=False,
no_schema=False, decode_attrs=True, cacert=None,
sasl_nocanon=False):
sasl_nocanon=True):
"""Create LDAPClient object.
:param ldap_uri: The LDAP URI to connect to
@ -1120,8 +1127,10 @@ class LDAPClient(object):
def _connect(self):
with self.error_handler():
conn = ldap_initialize(self.ldap_uri, cacertfile=self._cacert)
if self._sasl_nocanon:
conn.set_option(ldap.OPT_X_SASL_NOCANON, ldap.OPT_ON)
# SASL_NOCANON is set to ON in Fedora's default ldap.conf and
# in the ldap_initialize() function.
if not self._sasl_nocanon:
conn.set_option(ldap.OPT_X_SASL_NOCANON, ldap.OPT_OFF)
if self._start_tls:
conn.start_tls_s()

View File

@ -728,11 +728,8 @@ class DomainValidator(object):
conn = ipaldap.LDAPClient(
ldap_uri,
no_schema=True,
decode_attrs=False,
sasl_nocanon=True)
# sasl_nocanon used to avoid hard requirement for PTR
# records pointing back to the same host name
decode_attrs=False
)
conn.gssapi_bind()
if basedn is None: