URL: https://github.com/freeipa/freeipa/pull/2628 Author: tiran Title: #2628: [WIP] Refactor LDAPClient Action: opened
PR body: """ **WIP** Simplify LDAPClient construction and ensure that LDAP connections are always secure (LDAP + STARTTLS, LDAPI, LDAPS) unless explicitly stated otherwise. """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/2628/head:pr2628 git checkout pr2628
From e7b10f9fb83f2dc04c6ebb424cd1aa4cbb853118 Mon Sep 17 00:00:00 2001 From: Christian Heimes <chei...@redhat.com> Date: Thu, 29 Nov 2018 14:49:43 +0100 Subject: [PATCH 1/3] Move realm_to_serverid/ldap_uri to ipaldap The helper function realm_to_serverid() and realm_to_ldap_uri() are useful outside the server installation framework. They are now in ipapython.ipaldap along other helpers for LDAP handling in FreeIPA. Signed-off-by: Christian Heimes <chei...@redhat.com> --- install/tools/ipactl.in | 4 ++-- ipapython/ipaldap.py | 14 ++++++++++++++ ipaserver/install/adtrustinstance.py | 3 ++- ipaserver/install/bindinstance.py | 3 ++- ipaserver/install/ca.py | 5 +++-- ipaserver/install/custodiainstance.py | 5 +++-- ipaserver/install/dsinstance.py | 7 ++++--- ipaserver/install/installutils.py | 10 ---------- ipaserver/install/ipa_backup.py | 4 ++-- ipaserver/install/ipa_restore.py | 8 ++++---- ipaserver/install/ipa_server_certinstall.py | 3 ++- ipaserver/install/krbinstance.py | 2 +- ipaserver/install/ldapupdate.py | 2 +- ipaserver/install/plugins/upload_cacrt.py | 2 +- ipaserver/install/server/install.py | 6 +++--- ipaserver/install/server/replicainstall.py | 5 ++--- ipaserver/install/server/upgrade.py | 12 +++++++----- ipaserver/install/upgradeinstance.py | 4 +++- ipatests/test_integration/test_uninstallation.py | 2 +- 19 files changed, 57 insertions(+), 44 deletions(-) diff --git a/install/tools/ipactl.in b/install/tools/ipactl.in index 82e7412b07..68e93a6139 100644 --- a/install/tools/ipactl.in +++ b/install/tools/ipactl.in @@ -30,7 +30,7 @@ from ipaserver.install import service, installutils from ipaserver.install.dsinstance import config_dirname from ipaserver.install.installutils import is_ipa_configured, ScriptError from ipalib import api, errors -from ipapython.ipaldap import LDAPClient +from ipapython.ipaldap import LDAPClient, realm_to_serverid from ipapython.ipautil import wait_for_open_ports, wait_for_open_socket from ipapython.ipautil import run from ipapython import config @@ -75,7 +75,7 @@ def is_dirsrv_debugging_enabled(): returns True or False """ debugging = False - serverid = installutils.realm_to_serverid(api.env.realm) + serverid = realm_to_serverid(api.env.realm) dselist = [config_dirname(serverid)] for dse in dselist: try: diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py index 066f65dc43..78330a4d1a 100644 --- a/ipapython/ipaldap.py +++ b/ipapython/ipaldap.py @@ -39,12 +39,14 @@ import ldap.sasl import ldap.filter from ldap.controls import SimplePagedResultsControl, GetEffectiveRightsControl +import ldapurl import six # pylint: disable=ipa-forbidden-import from ipalib import errors, x509, _ from ipalib.constants import LDAP_GENERALIZED_TIME_FORMAT # pylint: enable=ipa-forbidden-import +from ipaplatform.paths import paths from ipapython.ipautil import format_netloc, CIDict from ipapython.dn import DN from ipapython.dnsutil import DNSName @@ -90,6 +92,18 @@ ) +def realm_to_serverid(realm_name): + """Convert Kerberos realm name to 389-DS server id""" + return "-".join(realm_name.split(".")) + + +def realm_to_ldapi_uri(realm_name): + """Get ldapi:// URI to 389-DS's Unix socket""" + serverid = realm_to_serverid(realm_name) + socketname = paths.SLAPD_INSTANCE_SOCKET_TEMPLATE % (serverid,) + return 'ldapi://' + ldapurl.ldapUrlEscape(socketname) + + def ldap_initialize(uri, cacertfile=None): """Wrapper around ldap.initialize() diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py index a21be5fba3..d117e18d58 100644 --- a/ipaserver/install/adtrustinstance.py +++ b/ipaserver/install/adtrustinstance.py @@ -40,6 +40,7 @@ from ipalib import errors, api from ipalib.util import normalize_zone from ipapython.dn import DN +from ipapython import ipaldap from ipapython import ipautil import ipapython.errors @@ -178,7 +179,7 @@ def __setup_default_attributes(self): self.suffix = ipautil.realm_to_suffix(self.realm) self.ldapi_socket = "%%2fvar%%2frun%%2fslapd-%s.socket" % \ - installutils.realm_to_serverid(self.realm) + ipaldap.realm_to_serverid(self.realm) # DN definitions self.trust_dn = DN(api.env.container_trusts, self.suffix) diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py index 41c42c4b9c..be32bffe1d 100644 --- a/ipaserver/install/bindinstance.py +++ b/ipaserver/install/bindinstance.py @@ -40,6 +40,7 @@ from ipaserver.install import installutils from ipaserver.install import service from ipaserver.install import sysupgrade +from ipapython import ipaldap from ipapython import ipautil from ipapython import dnsutil from ipapython.dnsutil import DNSName @@ -803,7 +804,7 @@ def __setup_sub_dict(self): self.sub_dict = dict( FQDN=self.fqdn, - SERVER_ID=installutils.realm_to_serverid(self.realm), + SERVER_ID=ipaldap.realm_to_serverid(self.realm), SUFFIX=self.suffix, BINDKEYS_FILE=paths.NAMED_BINDKEYS_FILE, MANAGED_KEYS_DIR=paths.NAMED_MANAGED_KEYS_DIR, diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py index b30fbed654..2f08b279e2 100644 --- a/ipaserver/install/ca.py +++ b/ipaserver/install/ca.py @@ -22,6 +22,7 @@ from ipapython.install.core import group, knob, extend_knob from ipaserver.install import cainstance, bindinstance, dsinstance from ipapython import ipautil, certdb +from ipapython import ipaldap from ipapython.admintool import ScriptError from ipaplatform import services from ipaplatform.paths import paths @@ -209,7 +210,7 @@ def install_check(standalone, replica_config, options): if standalone: dirname = dsinstance.config_dirname( - installutils.realm_to_serverid(realm_name)) + ipaldap.realm_to_serverid(realm_name)) cadb = certs.CertDB(realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR, subject_base=options._subject_base) dsdb = certs.CertDB( @@ -343,7 +344,7 @@ def install_step_1(standalone, replica_config, options, custodia): # ca.setup_lightweight_ca_key_retrieval() - serverid = installutils.realm_to_serverid(realm_name) + serverid = ipaldap.realm_to_serverid(realm_name) if standalone and replica_config is None: dirname = dsinstance.config_dirname(serverid) diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py index e856e851d5..383c17f4eb 100644 --- a/ipaserver/install/custodiainstance.py +++ b/ipaserver/install/custodiainstance.py @@ -5,6 +5,7 @@ import enum import logging +import ipapython.ipaldap from ipalib import api from ipaserver.secrets.kem import IPAKEMKeys, KEMLdap from ipaserver.secrets.client import CustodiaClient @@ -104,7 +105,7 @@ def __init__(self, host_name=None, realm=None, custodia_peer=None): @property def ldap_uri(self): if self.custodia_peer is None: - return installutils.realm_to_ldapi_uri(self.realm) + return ipapython.ipaldap.realm_to_ldapi_uri(self.realm) else: return "ldap://{}".format(self.custodia_peer) @@ -117,7 +118,7 @@ def __config_file(self): IPA_CUSTODIA_KEYS=paths.IPA_CUSTODIA_KEYS, IPA_CUSTODIA_SOCKET=paths.IPA_CUSTODIA_SOCKET, IPA_CUSTODIA_AUDIT_LOG=paths.IPA_CUSTODIA_AUDIT_LOG, - LDAP_URI=installutils.realm_to_ldapi_uri(self.realm), + LDAP_URI=ipapython.ipaldap.realm_to_ldapi_uri(self.realm), UID=httpd_info.pw_uid, GID=httpd_info.pw_gid ) diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index 05b8daa50d..33ab3d122b 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -294,7 +294,7 @@ def init_info(self, realm_name, fqdn, domain_name, dm_password, idstart, idmax, pkcs12_info, ca_file=None, setup_pkinit=False): self.realm = realm_name.upper() - self.serverid = installutils.realm_to_serverid(self.realm) + self.serverid = ipaldap.realm_to_serverid(self.realm) self.suffix = ipautil.realm_to_suffix(self.realm) self.fqdn = fqdn self.dm_password = dm_password @@ -1217,7 +1217,8 @@ def add_ca_cert(self, cacert_fname, cacert_name=''): # shutdown the server self.stop() - dirname = config_dirname(installutils.realm_to_serverid(self.realm)) + dirname = config_dirname( + ipaldap.realm_to_serverid(self.realm)) certdb = certs.CertDB( self.realm, nssdir=dirname, @@ -1362,7 +1363,7 @@ def request_service_keytab(self): def write_certmap_conf(realm, ca_subject): """(Re)write certmap.conf with given CA subject DN.""" - serverid = installutils.realm_to_serverid(realm) + serverid = ipaldap.realm_to_serverid(realm) ds_dirname = config_dirname(serverid) certmap_filename = os.path.join(ds_dirname, "certmap.conf") shutil.copyfile( diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index b0e8f93bf4..d58338ab0f 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -41,7 +41,6 @@ from dns import resolver, rdatatype from dns.exception import DNSException import ldap -import ldapurl import six from ipalib.install import sysrestore @@ -1106,15 +1105,6 @@ def check_version(): else: raise UpgradeMissingVersionError("no data_version stored") -def realm_to_serverid(realm_name): - return "-".join(realm_name.split(".")) - - -def realm_to_ldapi_uri(realm_name): - serverid = realm_to_serverid(realm_name) - socketname = paths.SLAPD_INSTANCE_SOCKET_TEMPLATE % (serverid,) - return 'ldapi://' + ldapurl.ldapUrlEscape(socketname) - def check_creds(options, realm_name): diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py index a5cdf20ad6..90d16d68ff 100644 --- a/ipaserver/install/ipa_backup.py +++ b/ipaserver/install/ipa_backup.py @@ -320,7 +320,7 @@ def run(self): logger.info('Stopping IPA services') run([paths.IPACTL, 'stop']) - instance = installutils.realm_to_serverid(api.env.realm) + instance = ipaldap.realm_to_serverid(api.env.realm) if os.path.exists(paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE % instance): if os.path.exists(paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE % @@ -364,7 +364,7 @@ def add_instance_specific_data(self): NOTE: this adds some things that may not get backed up. ''' - serverid = installutils.realm_to_serverid(api.env.realm) + serverid = ipaldap.realm_to_serverid(api.env.realm) for dir in [paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, paths.VAR_LIB_DIRSRV_INSTANCE_SCRIPTS_TEMPLATE % serverid, diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py index 1916d30631..3c9b3fea88 100644 --- a/ipaserver/install/ipa_restore.py +++ b/ipaserver/install/ipa_restore.py @@ -460,7 +460,7 @@ def get_connection(self): ''' Create an ldapi connection and bind to it using autobind as root. ''' - instance_name = installutils.realm_to_serverid(api.env.realm) + instance_name = ipaldap.realm_to_serverid(api.env.realm) if not services.knownservices.dirsrv.is_running(instance_name): raise admintool.ScriptError( @@ -863,7 +863,7 @@ def cert_restore_prepare(self): httpinstance.HTTPInstance().stop_tracking_certificates() try: dsinstance.DsInstance().stop_tracking_certificates( - installutils.realm_to_serverid(api.env.realm)) + ipaldap.realm_to_serverid(api.env.realm)) except (OSError, IOError): # When IPA is not installed, DS NSS DB does not exist pass @@ -894,13 +894,13 @@ def init_api(self, **overrides): api.bootstrap(in_server=True, context='restore', **overrides) api.finalize() - self.instances = [installutils.realm_to_serverid(api.env.realm)] + self.instances = [ipaldap.realm_to_serverid(api.env.realm)] self.backends = ['userRoot', 'ipaca'] # no IPA config means we are reinstalling from nothing so # there is nothing to test the DM password against. if os.path.exists(paths.IPA_DEFAULT_CONF): - instance_name = installutils.realm_to_serverid(api.env.realm) + instance_name = ipapython.ipaldap.realm_to_serverid(api.env.realm) if not services.knownservices.dirsrv.is_running(instance_name): raise admintool.ScriptError( "directory server instance is not running" diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py index 7901f0a739..ac0134086e 100644 --- a/ipaserver/install/ipa_server_certinstall.py +++ b/ipaserver/install/ipa_server_certinstall.py @@ -30,6 +30,7 @@ from ipapython import admintool from ipapython.certdb import NSSDatabase, get_ca_nickname from ipapython.dn import DN +from ipapython import ipaldap from ipalib import api, errors from ipaserver.install import certs, dsinstance, installutils, krbinstance @@ -125,7 +126,7 @@ def run(self): api.Backend.ldap2.disconnect() def install_dirsrv_cert(self): - serverid = installutils.realm_to_serverid(api.env.realm) + serverid = ipaldap.realm_to_serverid(api.env.realm) dirname = dsinstance.config_dirname(serverid) conn = api.Backend.ldap2 diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py index 4ead1c55f1..287e1781c2 100644 --- a/ipaserver/install/krbinstance.py +++ b/ipaserver/install/krbinstance.py @@ -262,7 +262,7 @@ def __setup_sub_dict(self): SUFFIX=self.suffix, DOMAIN=self.domain, HOST=self.host, - SERVER_ID=installutils.realm_to_serverid(self.realm), + SERVER_ID=ipaldap.realm_to_serverid(self.realm), REALM=self.realm, KRB5KDC_KADM5_ACL=paths.KRB5KDC_KADM5_ACL, DICT_WORDS=paths.DICT_WORDS, diff --git a/ipaserver/install/ldapupdate.py b/ipaserver/install/ldapupdate.py index aff45bbede..e6c1bd443f 100644 --- a/ipaserver/install/ldapupdate.py +++ b/ipaserver/install/ldapupdate.py @@ -272,7 +272,7 @@ def __init__(self, dm_password=None, sub_dict={}, self.realm = api.env.realm suffix = ipautil.realm_to_suffix(self.realm) if self.realm else None - self.ldapuri = installutils.realm_to_ldapi_uri(self.realm) + self.ldapuri = ipaldap.realm_to_ldapi_uri(self.realm) if suffix is not None: assert isinstance(suffix, DN) diff --git a/ipaserver/install/plugins/upload_cacrt.py b/ipaserver/install/plugins/upload_cacrt.py index 763da1e142..16b5e80c6a 100644 --- a/ipaserver/install/plugins/upload_cacrt.py +++ b/ipaserver/install/plugins/upload_cacrt.py @@ -21,7 +21,7 @@ from ipalib.install import certstore from ipaserver.install import certs, dsinstance -from ipaserver.install.installutils import realm_to_serverid +from ipapython.ipaldap import realm_to_serverid from ipalib import Registry, errors from ipalib import Updater from ipapython import certdb diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py index efccca77bd..b4c57752ff 100644 --- a/ipaserver/install/server/install.py +++ b/ipaserver/install/server/install.py @@ -22,6 +22,7 @@ from ipapython import ipautil, version from ipapython.ipautil import ( ipa_generate_password, run, user_input) +from ipapython import ipaldap from ipapython.admintool import ScriptError from ipaplatform import services from ipaplatform.paths import paths @@ -591,8 +592,7 @@ def install_check(installer): xmlrpc_uri = 'https://{0}/ipa/xml'.format( ipautil.format_netloc(host_name)) - ldapi_uri = 'ldapi://%2fvar%2frun%2fslapd-{0}.socket\n'.format( - installutils.realm_to_serverid(realm_name)) + ldapi_uri = ipaldap.realm_to_ldapi_uri(realm_name) # [global] section gopts = [ @@ -1166,7 +1166,7 @@ def uninstall(installer): # Note that this name will be wrong after the first uninstall. dirname = dsinstance.config_dirname( - installutils.realm_to_serverid(api.env.realm)) + ipaldap.realm_to_serverid(api.env.realm)) dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, paths.HTTPD_ALIAS_DIR] ids = certmonger.check_state(dirs) if ids: diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index 1a173e64d0..5001606890 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -220,8 +220,7 @@ def create_ipa_conf(fstore, config, ca_enabled, master=None): else: xmlrpc_uri = 'https://{0}/ipa/xml'.format( ipautil.format_netloc(config.host_name)) - ldapi_uri = 'ldapi://%2fvar%2frun%2fslapd-{0}.socket\n'.format( - installutils.realm_to_serverid(config.realm_name)) + ldapi_uri = ipaldap.realm_to_ldapi_uri(config.realm_name) # [global] section gopts = [ @@ -802,7 +801,7 @@ def promote_check(installer): api.bootstrap(in_server=True, context='installer', confdir=paths.ETC_IPA, - ldap_uri=installutils.realm_to_ldapi_uri(env.realm), + ldap_uri=ipaldap.realm_to_ldapi_uri(env.realm), xmlrpc_uri=xmlrpc_uri) # pylint: enable=no-member api.finalize() diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py index f1e78beb27..7567f6eb58 100644 --- a/ipaserver/install/server/upgrade.py +++ b/ipaserver/install/server/upgrade.py @@ -17,6 +17,7 @@ from contextlib import contextmanager from augeas import Augeas import dns.exception + from ipalib import api, x509 from ipalib.install import certmonger, sysrestore import SSSDConfig @@ -27,6 +28,7 @@ from ipaplatform import services from ipaplatform.tasks import tasks from ipapython import ipautil, version +from ipapython import ipaldap from ipapython import dnsutil, directivesetter from ipapython.dn import DN from ipaplatform.constants import constants @@ -939,7 +941,7 @@ def certificate_renewal_update(ca, ds, http): """ template = paths.CERTMONGER_COMMAND_TEMPLATE - serverid = installutils.realm_to_serverid(api.env.realm) + serverid = ipaldap.realm_to_serverid(api.env.realm) requests = [ { @@ -1357,7 +1359,7 @@ def fix_schema_file_syntax(): logger.info('Syntax already fixed') return - serverid = installutils.realm_to_serverid(api.env.realm) + serverid = ipaldap.realm_to_serverid(api.env.realm) ds_dir = dsinstance.config_dirname(serverid) # 1. 60ipadns.ldif: Add parenthesis to idnsRecord @@ -1432,7 +1434,7 @@ def remove_ds_ra_cert(subject_base): return dbdir = dsinstance.config_dirname( - installutils.realm_to_serverid(api.env.realm)) + ipaldap.realm_to_serverid(api.env.realm)) dsdb = certs.CertDB(api.env.realm, nssdir=dbdir, subject_base=subject_base) nickname = 'CN=IPA RA,%s' % subject_base @@ -1763,7 +1765,7 @@ def upgrade_configuration(): fqdn = api.env.host # Ok, we are an IPA server, do the additional tests - ds_serverid = installutils.realm_to_serverid(api.env.realm) + ds_serverid = ipaldap.realm_to_serverid(api.env.realm) ds = dsinstance.DsInstance() # start DS, CA will not start without running DS, and cause error @@ -2049,7 +2051,7 @@ def upgrade_configuration(): SUFFIX=krb.suffix, DOMAIN=api.env.domain, HOST=api.env.host, - SERVER_ID=installutils.realm_to_serverid(krb.realm), + SERVER_ID=ipaldap.realm_to_serverid(krb.realm), REALM=krb.realm, KRB5KDC_KADM5_ACL=paths.KRB5KDC_KADM5_ACL, DICT_WORDS=paths.DICT_WORDS, diff --git a/ipaserver/install/upgradeinstance.py b/ipaserver/install/upgradeinstance.py index cb83d7bb18..e2b11b6140 100644 --- a/ipaserver/install/upgradeinstance.py +++ b/ipaserver/install/upgradeinstance.py @@ -25,9 +25,11 @@ import shutil import random import traceback + from ipalib import api from ipaplatform.paths import paths from ipaplatform import services +from ipapython import ipaldap from ipaserver.install import installutils from ipaserver.install import schemaupdate @@ -88,7 +90,7 @@ def __init__(self, realm_name, files=[], schema_files=[]): h = "%02x" % rand.randint(0,255) ext += h super(IPAUpgrade, self).__init__("dirsrv", realm_name=realm_name) - serverid = installutils.realm_to_serverid(realm_name) + serverid = ipaldap.realm_to_serverid(realm_name) self.filename = '%s/%s' % (paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, DSE) self.savefilename = '%s/%s.ipa.%s' % (paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, DSE, ext) self.files = files diff --git a/ipatests/test_integration/test_uninstallation.py b/ipatests/test_integration/test_uninstallation.py index 2b9b926065..4607e8b707 100644 --- a/ipatests/test_integration/test_uninstallation.py +++ b/ipatests/test_integration/test_uninstallation.py @@ -18,7 +18,7 @@ from ipatests.pytest_ipa.integration import tasks from ipaplatform.paths import paths from ipaserver.install import dsinstance -from ipaserver.install.installutils import realm_to_serverid +from ipapython.ipaldap import realm_to_serverid class TestUninstallBase(IntegrationTest): From b8ca10fa95375c71f7b75b8cae38e58e8f916e9c Mon Sep 17 00:00:00 2001 From: Christian Heimes <chei...@redhat.com> Date: Fri, 30 Nov 2018 10:28:02 +0100 Subject: [PATCH 2/3] Add constructors to ldap client Add LDAPClient.from_realm(), LDAPClient.from_hostname_secure(), and LDAPClient.from_hostname_plain() constructors. The simple_bind() method now also refuses to transmit a password over a plain, unencrypted line. LDAPClient.from_hostname_secure() uses start_tls and FreeIPA's CA cert by default. The constructor also automatically disables start_tls for ldaps and ldapi connections. Signed-off-by: Christian Heimes <chei...@redhat.com> --- install/tools/ipa-replica-manage.in | 2 -- ipapython/ipaldap.py | 53 +++++++++++++++++++++++------ ipaserver/install/ipa_backup.py | 4 +-- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/install/tools/ipa-replica-manage.in b/install/tools/ipa-replica-manage.in index 35d412c2e2..67f678d44a 100644 --- a/install/tools/ipa-replica-manage.in +++ b/install/tools/ipa-replica-manage.in @@ -1218,7 +1218,6 @@ def re_initialize(realm, thishost, fromhost, dirman_passwd, nolookup=False): # we did not replicate memberOf, do so now. if not agreement.single_value.get('nsDS5ReplicatedAttributeListTotal'): ds = dsinstance.DsInstance(realm_name=realm) - ds.ldapi = os.getegid() == 0 ds.init_memberof() def force_sync(realm, thishost, fromhost, dirman_passwd, nolookup=False): @@ -1238,7 +1237,6 @@ def force_sync(realm, thishost, fromhost, dirman_passwd, nolookup=False): repl.force_sync(repl.conn, fromhost) else: ds = dsinstance.DsInstance(realm_name=realm) - ds.ldapi = os.getegid() == 0 ds.replica_manage_time_skew(prevent=False) repl = replication.ReplicationManager(realm, fromhost, dirman_passwd) repl.force_sync(repl.conn, thishost) diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py index 78330a4d1a..1454c4b488 100644 --- a/ipapython/ipaldap.py +++ b/ipapython/ipaldap.py @@ -29,7 +29,6 @@ import contextlib import os import pwd -from urllib.parse import urlparse import warnings from cryptography import x509 as crypto_x509 @@ -777,16 +776,12 @@ def __init__(self, ldap_uri, start_tls=False, force_schema_updates=False, If true, attributes are decoded to Python types according to their syntax. """ - if ldap_uri is not None: - self.ldap_uri = ldap_uri - self.host = 'localhost' - self.port = None - url_data = urlparse(ldap_uri) - self._protocol = url_data.scheme - if self._protocol in ('ldap', 'ldaps'): - self.host = url_data.hostname - self.port = url_data.port - + self.ldap_uri = ldap_uri + self._protocol = ldap_uri.split('://', 1)[0] + assert self._protocol in {'ldaps', 'ldapi', 'ldap'} + if self._protocol in {'ldaps', 'ldapi'}: + # STARTTLS only applies to ldap:// + start_tls = False self._start_tls = start_tls self._force_schema_updates = force_schema_updates self._no_schema = no_schema @@ -799,6 +794,40 @@ def __init__(self, ldap_uri, start_tls=False, force_schema_updates=False, self._conn = self._connect() + @classmethod + def from_realm(cls, realm_name, **kwargs): + """Create a LDAPI connection to local 389-DS instance + """ + uri = realm_to_ldapi_uri(realm_name) + return cls(uri, start_tls=False, cacert=None, **kwargs) + + @classmethod + def from_hostname_secure(cls, hostname, cacert=paths.IPA_CA_CRT, + start_tls=True, **kwargs): + """Create LDAP or LDAPS connection to a remote 389-DS instance + + This constructor is opinionated and doesn't let you shoot yourself in + the foot. It always creates a secure connection. By default it + returns a LDAP connection to port 389 and performs STARTTLS using the + default CA cert. With start_tls=False, it creates a LDAPS connection + to port 636 instead. + """ + if start_tls: + uri = 'ldap://%s' % format_netloc(hostname, 389) + else: + uri = 'ldaps://%s' % format_netloc(hostname, 636) + return cls(uri, start_tls=start_tls, cacert=cacert, **kwargs) + + @classmethod + def from_hostname_plain(cls, hostname): + """Create a plain LDAP connection with TLS/SSL + + Note: A plain TLS connection should only be used in combination with + GSSAPI bind. + """ + uri = 'ldap://%s' % format_netloc(hostname, 389) + return cls(uri) + def __str__(self): return self.ldap_uri @@ -1166,6 +1195,8 @@ def simple_bind(self, bind_dn, bind_password, server_controls=None, """ Perform simple bind operation. """ + if self._protocol == 'ldap' and not self._start_tls and bind_password: + raise ValueError('simple_bind over insecure LDAP connection') with self.error_handler(): self._flush_schema() assert isinstance(bind_dn, DN) diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py index 90d16d68ff..a6af840f94 100644 --- a/ipaserver/install/ipa_backup.py +++ b/ipaserver/install/ipa_backup.py @@ -400,7 +400,7 @@ def get_connection(self): self._conn.external_bind() except Exception as e: logger.error("Unable to bind to LDAP server %s: %s", - self._conn.host, e) + self._conn.ldap_uri, e) return self._conn @@ -594,7 +594,7 @@ def create_header(self, data_only): "Unable to obtain list of master services, continuing anyway") except Exception as e: logger.error("Failed to read services from '%s': %s", - conn.host, e) + conn.ldap_uri, e) else: services_cns = [s.single_value['cn'] for s in services] From 1910c821f6e023a3354df2d2993009a86912b324 Mon Sep 17 00:00:00 2001 From: Christian Heimes <chei...@redhat.com> Date: Fri, 30 Nov 2018 10:28:32 +0100 Subject: [PATCH 3/3] Use new LDAPClient constructors Replace get_ldap_uri() + LDAPClient() with new LDAPClient constructors like LDAPClient.from_realm(). Some places now use LDAPI with external bind instead of LDAP with simple bind. Although the FQDN *should* resolve to 127.0.0.1 / [::1], there is no hard guarantee. The draft https://tools.ietf.org/html/draft-west-let-localhost-be-localhost-04#section-5.1 specifies that applications must verify that the resulting IP is a loopback API. LDAPI is always local and a bit more efficient, too. Signed-off-by: Christian Heimes <chei...@redhat.com> --- install/migration/migration.py | 2 +- ipaclient/install/client.py | 3 +- ipaclient/install/ipa_certupdate.py | 3 +- ipaserver/dcerpc.py | 5 +-- ipaserver/dnssec/ldapkeydb.py | 2 +- ipaserver/install/custodiainstance.py | 6 +-- ipaserver/install/dogtaginstance.py | 8 ++-- ipaserver/install/dsinstance.py | 57 +++++++++---------------- ipaserver/install/ipa_backup.py | 3 +- ipaserver/install/ipa_restore.py | 3 +- ipaserver/install/ldapupdate.py | 8 +++- ipaserver/install/replication.py | 37 +++++----------- ipatests/pytest_ipa/integration/host.py | 3 +- ipatests/test_install/test_updates.py | 3 +- 14 files changed, 54 insertions(+), 89 deletions(-) diff --git a/install/migration/migration.py b/install/migration/migration.py index 9b614fc9fc..7a5a046434 100644 --- a/install/migration/migration.py +++ b/install/migration/migration.py @@ -55,7 +55,7 @@ def bind(ldap_uri, base_dn, username, password): raise IOError(errno.EIO, 'Cannot get Base DN') bind_dn = DN(('uid', username), ('cn', 'users'), ('cn', 'accounts'), base_dn) try: - conn = ipaldap.LDAPClient(ldap_uri) + conn = ipaldap.LDAPClient(ldap_uri, start_tls=True) conn.simple_bind(bind_dn, password) except (errors.ACIError, errors.DatabaseError, errors.NotFound) as e: logger.error( diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py index fe3f0bb2b3..14bf34aa0e 100644 --- a/ipaclient/install/client.py +++ b/ipaclient/install/client.py @@ -1629,8 +1629,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) + conn = ipaldap.LDAPClient.from_hostname_plain(server) try: conn.gssapi_bind() certs = certstore.get_ca_certs(conn, base_dn, realm, ca_enabled) diff --git a/ipaclient/install/ipa_certupdate.py b/ipaclient/install/ipa_certupdate.py index c4aee1309b..f5e618a7b8 100644 --- a/ipaclient/install/ipa_certupdate.py +++ b/ipaclient/install/ipa_certupdate.py @@ -70,8 +70,7 @@ def run_with_args(api): """ server = urlsplit(api.env.jsonrpc_uri).hostname - ldap_uri = ipaldap.get_ldap_uri(server) - ldap = ipaldap.LDAPClient(ldap_uri) + ldap = ipaldap.LDAPClient.from_hostname_secure(server) tmpdir = tempfile.mkdtemp(prefix="tmp-") ccache_name = os.path.join(tmpdir, 'ccache') diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py index 5e841350b8..26a26176b2 100644 --- a/ipaserver/dcerpc.py +++ b/ipaserver/dcerpc.py @@ -723,9 +723,8 @@ def __search_in_dc(self, info, host, port, filter, attrs, scope, entries = None try: - ldap_uri = ipaldap.get_ldap_uri(host) - conn = ipaldap.LDAPClient( - ldap_uri, + conn = ipaldap.LDAPClient.from_hostname_secure( + host, no_schema=True, decode_attrs=False ) diff --git a/ipaserver/dnssec/ldapkeydb.py b/ipaserver/dnssec/ldapkeydb.py index d47b03732f..6bffba2bd2 100644 --- a/ipaserver/dnssec/ldapkeydb.py +++ b/ipaserver/dnssec/ldapkeydb.py @@ -467,7 +467,7 @@ def zone_keypairs(self): # LDAP initialization dns_dn = DN(ipalib.api.env.container_dns, ipalib.api.env.basedn) - ldap = ipaldap.LDAPClient(ipalib.api.env.ldap_uri) + ldap = ipaldap.LDAPClient(ipalib.api.env.ldap_uri, start_tls=True) logger.debug('Connecting to LDAP') # GSSAPI will be used, used has to be kinited already ldap.gssapi_bind() diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py index 383c17f4eb..00b2c4c446 100644 --- a/ipaserver/install/custodiainstance.py +++ b/ipaserver/install/custodiainstance.py @@ -5,7 +5,6 @@ import enum import logging -import ipapython.ipaldap from ipalib import api from ipaserver.secrets.kem import IPAKEMKeys, KEMLdap from ipaserver.secrets.client import CustodiaClient @@ -13,6 +12,7 @@ from ipaplatform.constants import constants from ipaserver.install.service import SimpleServiceInstance from ipapython import ipautil +from ipapython import ipaldap from ipapython.certdb import NSSDatabase from ipaserver.install import installutils from ipaserver.install import ldapupdate @@ -105,7 +105,7 @@ def __init__(self, host_name=None, realm=None, custodia_peer=None): @property def ldap_uri(self): if self.custodia_peer is None: - return ipapython.ipaldap.realm_to_ldapi_uri(self.realm) + return ipaldap.realm_to_ldapi_uri(self.realm) else: return "ldap://{}".format(self.custodia_peer) @@ -118,7 +118,7 @@ def __config_file(self): IPA_CUSTODIA_KEYS=paths.IPA_CUSTODIA_KEYS, IPA_CUSTODIA_SOCKET=paths.IPA_CUSTODIA_SOCKET, IPA_CUSTODIA_AUDIT_LOG=paths.IPA_CUSTODIA_AUDIT_LOG, - LDAP_URI=ipapython.ipaldap.realm_to_ldapi_uri(self.realm), + LDAP_URI=ipaldap.realm_to_ldapi_uri(self.realm), UID=httpd_info.pw_uid, GID=httpd_info.pw_gid ) diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py index d58561732e..9b043c6d77 100644 --- a/ipaserver/install/dogtaginstance.py +++ b/ipaserver/install/dogtaginstance.py @@ -385,8 +385,7 @@ def get_admin_cert(self): conn = None try: - ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=self.realm) - conn = ipaldap.LDAPClient(ldap_uri) + conn = ipaldap.LDAPClient.from_realm(self.realm) conn.external_bind() entry_attrs = conn.get_entry(self.admin_dn, ['usercertificate']) @@ -464,8 +463,9 @@ def setup_admin(self): wait_groups.append(group_dn) # Now wait until the other server gets replicated this data - ldap_uri = ipaldap.get_ldap_uri(self.master_host) - master_conn = ipaldap.LDAPClient(ldap_uri, start_tls=True) + master_conn = ipaldap.LDAPClient.from_hostname_secure( + self.master_host + ) logger.debug( "Waiting for %s to appear on %s", self.admin_dn, master_conn ) diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index 33ab3d122b..6cdec5c5fc 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -162,18 +162,17 @@ def is_ds_running(server_id=''): def get_domain_level(api=api): - ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) - conn = ipaldap.LDAPClient(ldap_uri) - conn.external_bind() - dn = DN(('cn', 'Domain Level'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn) - try: - entry = conn.get_entry(dn, ['ipaDomainLevel']) - except errors.NotFound: - return constants.DOMAIN_LEVEL_0 - return int(entry.single_value['ipaDomainLevel']) + with ipaldap.LDAPClient.from_realm(api.env.realm) as conn: + conn.external_bind() + try: + entry = conn.get_entry(dn, ['ipaDomainLevel']) + except errors.NotFound: + return constants.DOMAIN_LEVEL_0 + else: + return int(entry.single_value['ipaDomainLevel']) def get_all_external_schema_files(root): @@ -418,8 +417,7 @@ def create_replica(self, realm_name, master_fqdn, fqdn, def _get_replication_manager(self): # Always connect to self over ldapi - ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=self.realm) - conn = ipaldap.LDAPClient(ldap_uri) + conn = ipaldap.LDAPClient.from_realm(self.realm) conn.external_bind() repl = replication.ReplicationManager( self.realm, self.fqdn, self.dm_password, conn=conn @@ -706,7 +704,6 @@ def __add_memberof_module(self): self._ldap_mod("memberof-conf.ldif") def init_memberof(self): - if not self.run_init_memberof: return @@ -715,15 +712,9 @@ def init_memberof(self): dn = DN(('cn', 'IPA install %s' % self.sub_dict["TIME"]), ('cn', 'memberof task'), ('cn', 'tasks'), ('cn', 'config')) logger.debug("Waiting for memberof task to complete.") - ldap_uri = ipaldap.get_ldap_uri(self.fqdn) - conn = ipaldap.LDAPClient(ldap_uri) - if self.dm_password: - conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, - bind_password=self.dm_password) - else: - conn.gssapi_bind() - replication.wait_for_task(conn, dn) - conn.unbind() + with ipaldap.LDAPClient.from_realm(self.realm) as conn: + conn.external_bind() + replication.wait_for_task(conn, dn) def apply_updates(self): schema_files = get_all_external_schema_files(paths.EXTERNAL_SCHEMA_DIR) @@ -887,10 +878,9 @@ def __enable_ssl(self): self.cacert_name = dsdb.cacert_name - ldap_uri = ipaldap.get_ldap_uri(self.fqdn) - conn = ipaldap.LDAPClient(ldap_uri) - conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, - bind_password=self.dm_password) + # use LDAPI? + conn = ipaldap.LDAPClient.from_realm(self.realm) + conn.external_bind() encrypt_entry = conn.make_entry( DN(('cn', 'encryption'), ('cn', 'config')), @@ -943,10 +933,8 @@ def __upload_ca_cert(self): subject_base=self.subject_base) trust_flags = dict(reversed(dsdb.list_certs())) - ldap_uri = ipaldap.get_ldap_uri(self.fqdn) - conn = ipaldap.LDAPClient(ldap_uri) - conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, - bind_password=self.dm_password) + conn = ipaldap.LDAPClient.from_realm(self.realm) + conn.external_bind() nicknames = dsdb.find_root_cert(self.cacert_name)[:-1] for nickname in nicknames: @@ -977,14 +965,9 @@ def __import_ca_certs(self): dsdb = certs.CertDB(self.realm, nssdir=dirname, subject_base=self.subject_base) - ldap_uri = ipaldap.get_ldap_uri(self.fqdn) - conn = ipaldap.LDAPClient(ldap_uri) - conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, - bind_password=self.dm_password) - - self.export_ca_certs_nssdb(dsdb, self.ca_is_configured, conn) - - conn.unbind() + with ipaldap.LDAPClient.from_realm(self.realm) as conn: + conn.external_bind() + self.export_ca_certs_nssdb(dsdb, self.ca_is_configured, conn) def __add_default_layout(self): self._ldap_mod("bootstrap-template.ldif", self.sub_dict) diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py index a6af840f94..9d74000eb4 100644 --- a/ipaserver/install/ipa_backup.py +++ b/ipaserver/install/ipa_backup.py @@ -393,8 +393,7 @@ def get_connection(self): if self._conn is not None: return self._conn - ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) - self._conn = ipaldap.LDAPClient(ldap_uri) + self._conn = ipaldap.LDAPClient.from_realm(api.env.realm) try: self._conn.external_bind() diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py index 3c9b3fea88..e978004188 100644 --- a/ipaserver/install/ipa_restore.py +++ b/ipaserver/install/ipa_restore.py @@ -470,8 +470,7 @@ def get_connection(self): if self._conn is not None: return self._conn - ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) - self._conn = ipaldap.LDAPClient(ldap_uri) + self._conn = ipaldap.LDAPClient.from_realm(api.env.realm) try: self._conn.external_bind() diff --git a/ipaserver/install/ldapupdate.py b/ipaserver/install/ldapupdate.py index e6c1bd443f..b5f54418c7 100644 --- a/ipaserver/install/ldapupdate.py +++ b/ipaserver/install/ldapupdate.py @@ -54,8 +54,12 @@ def connect(ldapi=False, realm=None, fqdn=None, dm_password=None): """Create a connection for updates""" - ldap_uri = ipaldap.get_ldap_uri(fqdn, ldapi=ldapi, realm=realm) - conn = ipaldap.LDAPClient(ldap_uri, decode_attrs=False) + if ldapi: + conn = ipaldap.LDAPClient.from_realm(realm, decode_attrs=False) + else: + conn = ipaldap.LDAPClient.from_hostname_secure( + fqdn, decode_attrs=False + ) try: if dm_password: conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py index d25b9372c6..df6616808c 100644 --- a/ipaserver/install/replication.py +++ b/ipaserver/install/replication.py @@ -137,8 +137,7 @@ def enable_replication_version_checking(realm, dirman_passwd): enabled then enable it and restart 389-ds. If it is enabled the do nothing. """ - ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=realm) - conn = ipaldap.LDAPClient(ldap_uri) + conn = ipaldap.LDAPClient.from_realm(realm) if dirman_passwd: conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=dirman_passwd) @@ -595,8 +594,9 @@ def finalize_replica_config(self, r_hostname, r_binddn=None, """ self._finalize_replica_settings(self.conn) - ldap_uri = ipaldap.get_ldap_uri(r_hostname) - r_conn = ipaldap.LDAPClient(ldap_uri, cacert=cacert) + r_conn = ipaldap.LDAPClient.from_hostname_secure( + r_hostname, cacert=cacert + ) if r_bindpw: r_conn.simple_bind(r_binddn, r_bindpw) else: @@ -1127,12 +1127,7 @@ def setup_replication(self, r_hostname, r_port=389, r_sslport=636, local_port = r_port # note - there appears to be a bug in python-ldap - it does not # allow connections using two different CA certs - ldap_uri = ipaldap.get_ldap_uri(r_hostname, r_port, - cacert=paths.IPA_CA_CRT, - protocol='ldap') - r_conn = ipaldap.LDAPClient(ldap_uri, - cacert=paths.IPA_CA_CRT, - start_tls=True) + r_conn = ipaldap.LDAPClient.from_hostname_secure(r_hostname) if r_bindpw: r_conn.simple_bind(r_binddn, r_bindpw) @@ -1238,9 +1233,7 @@ def setup_winsync_replication(self, raise RuntimeError("Failed to start replication") def convert_to_gssapi_replication(self, r_hostname, r_binddn, r_bindpw): - ldap_uri = ipaldap.get_ldap_uri(r_hostname, PORT, - cacert=paths.IPA_CA_CRT) - r_conn = ipaldap.LDAPClient(ldap_uri, cacert=paths.IPA_CA_CRT) + r_conn = ipaldap.LDAPClient.from_hostname_secure(r_hostname) if r_bindpw: r_conn.simple_bind(r_binddn, r_bindpw) else: @@ -1268,11 +1261,7 @@ def setup_gssapi_replication(self, r_hostname, r_binddn=None, r_bindpw=None): Only usable to connect 2 existing replicas (needs existing kerberos principals) """ - # note - there appears to be a bug in python-ldap - it does not - # allow connections using two different CA certs - ldap_uri = ipaldap.get_ldap_uri(r_hostname, PORT, - cacert=paths.IPA_CA_CRT) - r_conn = ipaldap.LDAPClient(ldap_uri, cacert=paths.IPA_CA_CRT) + r_conn = ipaldap.LDAPClient.from_hostname_secure(r_hostname) if r_bindpw: r_conn.simple_bind(r_binddn, r_bindpw) else: @@ -1768,10 +1757,8 @@ def remove_temp_replication_user(self, conn, r_hostname): def setup_promote_replication(self, r_hostname, r_binddn=None, r_bindpw=None, cacert=paths.IPA_CA_CRT): - # note - there appears to be a bug in python-ldap - it does not - # allow connections using two different CA certs - ldap_uri = ipaldap.get_ldap_uri(r_hostname) - r_conn = ipaldap.LDAPClient(ldap_uri, cacert=cacert) + r_conn = ipaldap.LDAPClient.from_hostname_secure( + r_hostname, cacert=cacert) if r_bindpw: r_conn.simple_bind(r_binddn, r_bindpw) else: @@ -1910,8 +1897,7 @@ class CAReplicationManager(ReplicationManager): def __init__(self, realm, hostname): # Always connect to self over ldapi - ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=realm) - conn = ipaldap.LDAPClient(ldap_uri) + conn = ipaldap.LDAPClient.from_realm(realm) conn.external_bind() super(CAReplicationManager, self).__init__( realm, hostname, None, port=DEFAULT_PORT, conn=conn) @@ -1923,8 +1909,7 @@ def setup_cs_replication(self, r_hostname): Assumes a promote replica with working GSSAPI for replication and unified DS instance. """ - ldap_uri = ipaldap.get_ldap_uri(r_hostname) - r_conn = ipaldap.LDAPClient(ldap_uri) + r_conn = ipaldap.LDAPClient.from_hostname_secure(r_hostname) r_conn.gssapi_bind() # Setup the first half diff --git a/ipatests/pytest_ipa/integration/host.py b/ipatests/pytest_ipa/integration/host.py index 28f6e2cd32..8aa796c5ea 100644 --- a/ipatests/pytest_ipa/integration/host.py +++ b/ipatests/pytest_ipa/integration/host.py @@ -44,8 +44,7 @@ def ldap_connect(self): """Return an LDAPClient authenticated to this host as directory manager """ self.log.info('Connecting to LDAP at %s', self.external_hostname) - ldap_uri = ipaldap.get_ldap_uri(self.external_hostname) - ldap = ipaldap.LDAPClient(ldap_uri) + ldap = ipaldap.LDAPClient.from_hostname_secure(self.external_hostname) binddn = self.config.dirman_dn self.log.info('LDAP bind as %s' % binddn) ldap.simple_bind(binddn, self.config.dirman_password) diff --git a/ipatests/test_install/test_updates.py b/ipatests/test_install/test_updates.py index dc88f2fbeb..5e9b2cac8e 100644 --- a/ipatests/test_install/test_updates.py +++ b/ipatests/test_install/test_updates.py @@ -65,8 +65,7 @@ def setUp(self): else: raise unittest.SkipTest("No directory manager password") self.updater = LDAPUpdate(dm_password=self.dm_password, sub_dict={}) - ldap_uri = ipaldap.get_ldap_uri(fqdn) - self.ld = ipaldap.LDAPClient(ldap_uri) + self.ld = ipaldap.LDAPClient.from_hostname_secure(fqdn) self.ld.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) self.testdir = os.path.abspath(os.path.dirname(__file__))
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org