diff options
| author | Tomas Krizek <tkrizek@redhat.com> | 2016-11-01 14:52:33 +0100 |
|---|---|---|
| committer | Martin Basti <mbasti@redhat.com> | 2016-11-07 11:34:03 +0100 |
| commit | 5b81dbfda1e4f0799d4ce87e9987a896af3ff299 (patch) | |
| tree | bf0b256dec17a5e9ca7bacb414488cb0436aba49 | |
| parent | 4f1a6a177666c475156f496d3f7719b37e66a7b0 (diff) | |
| download | freeipa-5b81dbfda1e4f0799d4ce87e9987a896af3ff299.tar.gz freeipa-5b81dbfda1e4f0799d4ce87e9987a896af3ff299.tar.xz freeipa-5b81dbfda1e4f0799d4ce87e9987a896af3ff299.zip | |
ipaldap: merge IPAdmin to LDAPClient
* move IPAdmin methods to LDAPClient
* add extra arguments (cacert, sasl_nocanon) to LDAPClient.__init__()
* add host, port, _protocol to LDAPClient (parsed from ldap_uri)
* create get_ldap_uri() method to create ldap_uri from former
IPAdmin.__init__() arguments
* replace IPAdmin with LDAPClient + get_ldap_uri()
* remove ununsed function argument hostname from
enable_replication_version_checking()
https://fedorahosted.org/freeipa/ticket/6461
Reviewed-By: Martin Basti <mbasti@redhat.com>
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
26 files changed, 187 insertions, 210 deletions
diff --git a/client/ipa-client-install b/client/ipa-client-install index 625eaf3a1..639810b62 100755 --- a/client/ipa-client-install +++ b/client/ipa-client-install @@ -1877,7 +1877,8 @@ def print_port_conf_info(): " UDP: 464, 123 (if NTP enabled)") def get_certs_from_ldap(server, base_dn, realm, ca_enabled): - conn = ipaldap.IPAdmin(server, sasl_nocanon=True) + ldap_uri = ipaldap.get_ldap_uri(server) + conn = ipaldap.LDAPClient(ldap_uri, sasl_nocanon=True) try: conn.gssapi_bind() certs = certstore.get_ca_certs(conn, base_dn, realm, ca_enabled) diff --git a/install/migration/migration.py b/install/migration/migration.py index a87b488fc..4743279be 100644 --- a/install/migration/migration.py +++ b/install/migration/migration.py @@ -26,7 +26,7 @@ from wsgiref.util import request_uri from ipapython.ipa_log_manager import root_logger from ipapython.dn import DN -from ipapython.ipaldap import IPAdmin +from ipapython import ipaldap from ipalib import errors, create_api @@ -48,7 +48,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 = IPAdmin(ldap_uri=ldap_uri) + conn = ipaldap.LDAPClient(ldap_uri) conn.simple_bind(bind_dn, password) except (errors.ACIError, errors.DatabaseError, errors.NotFound) as e: root_logger.error( diff --git a/install/tools/ipa-csreplica-manage b/install/tools/ipa-csreplica-manage index b5474eb45..85b55d144 100755 --- a/install/tools/ipa-csreplica-manage +++ b/install/tools/ipa-csreplica-manage @@ -93,7 +93,8 @@ def list_replicas(realm, host, replica, dirman_passwd, verbose): try: # connect to main IPA LDAP server - conn = ipaldap.IPAdmin(host, 636, cacert=CACERT) + ldap_uri = ipaldap.get_ldap_uri(host, 636, cacert=CACERT) + conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT) conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=dirman_passwd) @@ -295,7 +296,8 @@ def add_link(realm, replica1, replica2, dirman_passwd, options): except Exception as e: sys.exit(str(e)) try: - conn = ipaldap.IPAdmin(replica2, 636, cacert=CACERT) + ldap_uri = ipaldap.get_ldap_uri(replica2, 636, cacert=CACERT) + conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT) conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=dirman_passwd) diff --git a/install/tools/ipa-httpd-kdcproxy b/install/tools/ipa-httpd-kdcproxy index d64420640..20674c26c 100755 --- a/install/tools/ipa-httpd-kdcproxy +++ b/install/tools/ipa-httpd-kdcproxy @@ -29,7 +29,7 @@ import sys from ipalib import api, errors from ipapython.ipa_log_manager import standard_logging_setup -from ipapython.ipaldap import IPAdmin +from ipapython.ipaldap import LDAPClient from ipapython.dn import DN from ipaplatform.paths import paths @@ -78,9 +78,7 @@ class KDCProxyConfig(object): """Establish LDAP connection""" self.log.debug('ldap_uri: %s', self.ldap_uri) try: - self.con = IPAdmin(ldap_uri=self.ldap_uri) - # EXTERNAL bind as root user - self.con.ldapi = True + self.con = LDAPClient(self.ldap_uri) self.con.do_bind() except (errors.NetworkError, socket.timeout) as e: msg = 'Unable to connect to dirsrv: %s' % e @@ -94,7 +92,7 @@ class KDCProxyConfig(object): self.log.exception(msg) raise FatalError(msg) - def _find_entry(self, dn, attrs, filter, scope=IPAdmin.SCOPE_BASE): + def _find_entry(self, dn, attrs, filter, scope=LDAPClient.SCOPE_BASE): """Find an LDAP entry, handles NotFound and Limit""" try: entries = self.con.get_entries( diff --git a/install/tools/ipa-managed-entries b/install/tools/ipa-managed-entries index 1c8f3f773..691811ed9 100755 --- a/install/tools/ipa-managed-entries +++ b/install/tools/ipa-managed-entries @@ -87,7 +87,8 @@ def main(): conn = None try: filter = '(objectClass=extensibleObject)' - conn = ipaldap.IPAdmin(host, 636, cacert=CACERT) + ldap_uri = ipaldap.get_ldap_uri(host, 636, cacert=CACERT) + conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT) if options.dirman_password: try: diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage index 2ec09a633..5abc1d582 100755 --- a/install/tools/ipa-replica-manage +++ b/install/tools/ipa-replica-manage @@ -167,7 +167,8 @@ def list_replicas(realm, host, replica, dirman_passwd, verbose, nolookup=False): peers = {} try: - conn = ipaldap.IPAdmin(host, 636, cacert=CACERT) + ldap_uri = ipaldap.get_ldap_uri(host, 636, cacert=CACERT) + conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT) if dirman_passwd: conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=dirman_passwd) @@ -627,7 +628,8 @@ def clean_dangling_ruvs(realm, host, options): Cleans all RUVs and CS-RUVs that are left in the system from uninstalled replicas """ - conn = ipaldap.IPAdmin(host, 636, cacert=CACERT) + ldap_uri = ipaldap.get_ldap_uri(host, 636, cacert=CACERT) + conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT) try: conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=options.dirman_passwd) @@ -674,7 +676,8 @@ def clean_dangling_ruvs(realm, host, options): offlines = set() for master_cn, master_info in info.items(): try: - conn = ipaldap.IPAdmin(master_cn, 636, cacert=CACERT) + ldap_uri = ipaldap.get_ldap_uri(master_cn, 636, cacert=CACERT) + conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT) conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=options.dirman_passwd) master_info['online'] = True diff --git a/install/tools/ipactl b/install/tools/ipactl index 354209310..13a1a272c 100755 --- a/install/tools/ipactl +++ b/install/tools/ipactl @@ -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 IPAdmin +from ipapython.ipaldap import LDAPClient from ipapython.ipautil import ( wait_for_open_ports, wait_for_open_socket, is_fips_enabled) from ipapython import config @@ -165,7 +165,7 @@ def get_config(dirsrv): else: (host, port) = lurl.hostport.split(':') wait_for_open_ports(host, [int(port)], timeout=api.env.startup_timeout) - con = IPAdmin(ldap_uri=api.env.ldap_uri) + con = LDAPClient(api.env.ldap_uri) con.external_bind() res = con.get_entries( base, diff --git a/ipaclient/ipa_certupdate.py b/ipaclient/ipa_certupdate.py index 0781f3936..3678decc2 100644 --- a/ipaclient/ipa_certupdate.py +++ b/ipaclient/ipa_certupdate.py @@ -56,7 +56,8 @@ class CertUpdate(admintool.AdminTool): api.finalize() server = urlsplit(api.env.jsonrpc_uri).hostname - ldap = ipaldap.IPAdmin(server) + ldap_uri = ipaldap.get_ldap_uri(server) + ldap = ipaldap.LDAPClient(ldap_uri) tmpdir = tempfile.mkdtemp(prefix="tmp-") ccache_name = os.path.join(tmpdir, 'ccache') diff --git a/ipaclient/ipadiscovery.py b/ipaclient/ipadiscovery.py index e546ab061..46e05c971 100644 --- a/ipaclient/ipadiscovery.py +++ b/ipaclient/ipadiscovery.py @@ -376,15 +376,14 @@ class IPADiscovery(object): #now verify the server is really an IPA server try: - root_logger.debug("Init LDAP connection to: %s", thost) + ldap_uri = ipaldap.get_ldap_uri(thost) + start_tls = False if ca_cert_path: - lh = ipaldap.IPAdmin(thost, protocol='ldap', - cacert=ca_cert_path, start_tls=True, - no_schema=True, decode_attrs=False, - demand_cert=True) - else: - lh = ipaldap.IPAdmin(thost, protocol='ldap', - no_schema=True, decode_attrs=False) + start_tls = True + root_logger.debug("Init LDAP connection to: %s", ldap_uri) + lh = ipaldap.LDAPClient( + ldap_uri, cacert=ca_cert_path, start_tls=start_tls, + no_schema=True, decode_attrs=False) try: lh.simple_bind(DN(), '') diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py index a3e1b8776..2994c0144 100644 --- a/ipapython/ipaldap.py +++ b/ipapython/ipaldap.py @@ -27,6 +27,7 @@ import contextlib import collections import os import pwd +from urlparse import urlparse import ldap import ldap.sasl @@ -705,7 +706,8 @@ class LDAPClient(object): size_limit = 0 # unlimited def __init__(self, ldap_uri, start_tls=False, force_schema_updates=False, - no_schema=False, decode_attrs=True): + no_schema=False, decode_attrs=True, cacert=None, + sasl_nocanon=False): """Create LDAPClient object. :param ldap_uri: The LDAP URI to connect to @@ -727,6 +729,16 @@ class LDAPClient(object): self._force_schema_updates = force_schema_updates self._no_schema = no_schema self._decode_attrs = decode_attrs + self._cacert = cacert + self._sasl_nocanon = sasl_nocanon + + 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.log = log_mgr.get_logger(self) self._has_schema = False @@ -734,6 +746,36 @@ class LDAPClient(object): self._conn = self._connect() + def __str__(self): + return self.ldap_uri + + def do_bind(self, dm_password="", autobind=AUTOBIND_AUTO): + if dm_password: + self.simple_bind(bind_dn=DIRMAN_DN, + bind_password=dm_password) + return + if (autobind != AUTOBIND_DISABLED and os.getegid() == 0 and + self._protocol == 'ldapi'): + try: + # autobind + self.external_bind() + return + except errors.NotFound: + if autobind == AUTOBIND_ENABLED: + # autobind was required and failed, raise + # exception that it failed + raise + + # fall back + self.gssapi_bind() + + def modify_s(self, dn, modlist): + # FIXME: for backwards compatibility only + assert isinstance(dn, DN) + dn = str(dn) + modlist = [(a, self.encode(b), self.encode(c)) for a, b, c in modlist] + return self.conn.modify_s(dn, modlist) + @property def conn(self): return self._conn @@ -1066,6 +1108,14 @@ class LDAPClient(object): with self.error_handler(): conn = ldap.initialize(self.ldap_uri) + if self._start_tls or self._protocol == 'ldaps': + ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, self._cacert) + ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, True) + conn.set_option(ldap.OPT_X_TLS_DEMAND, True) + + if self._sasl_nocanon: + conn.set_option(ldap.OPT_X_SASL_NOCANON, ldap.OPT_ON) + if self._start_tls: conn.start_tls_s() @@ -1559,99 +1609,22 @@ class LDAPClient(object): return True -class IPAdmin(LDAPClient): +def get_ldap_uri(host='', port=389, cacert=None, ldapi=False, realm=None, + protocol=None): + if protocol is None: + if ldapi: + protocol = 'ldapi' + elif cacert is not None: + protocol = 'ldaps' + else: + protocol = 'ldap' - def __get_ldap_uri(self, protocol): if protocol == 'ldaps': - return 'ldaps://%s' % format_netloc(self.host, self.port) + return 'ldaps://%s' % format_netloc(host, port) elif protocol == 'ldapi': return 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % ( - "-".join(self.realm.split("."))) + "-".join(realm.split("."))) elif protocol == 'ldap': - return 'ldap://%s' % format_netloc(self.host, self.port) + return 'ldap://%s' % format_netloc(host, port) else: raise ValueError('Protocol %r not supported' % protocol) - - - def __guess_protocol(self): - """Return the protocol to use based on flags passed to the constructor - - Only used when "protocol" is not specified explicitly. - - If a CA certificate is provided then it is assumed that we are - doing SSL client authentication with proxy auth. - - If a CA certificate is not present then it is assumed that we are - using a forwarded kerberos ticket for SASL auth. SASL provides - its own encryption. - """ - if self.cacert is not None: - return 'ldaps' - elif self.ldapi: - return 'ldapi' - else: - return 'ldap' - - def __init__(self, host='', port=389, cacert=None, debug=None, ldapi=False, - realm=None, protocol=None, force_schema_updates=True, - start_tls=False, ldap_uri=None, no_schema=False, - decode_attrs=True, sasl_nocanon=False, demand_cert=False): - self._conn = None - log_mgr.get_logger(self, True) - if debug and debug.lower() == "on": - ldap.set_option(ldap.OPT_DEBUG_LEVEL,255) - if cacert is not None: - ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, cacert) - - self.port = port - self.host = host - self.cacert = cacert - self.ldapi = ldapi - self.realm = realm - self.suffixes = {} - - if not ldap_uri: - ldap_uri = self.__get_ldap_uri(protocol or self.__guess_protocol()) - - super(IPAdmin, self).__init__( - ldap_uri, force_schema_updates=force_schema_updates, - no_schema=no_schema, decode_attrs=decode_attrs) - - with self.error_handler(): - if demand_cert: - ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, True) - self.conn.set_option(ldap.OPT_X_TLS_DEMAND, True) - - if sasl_nocanon: - self.conn.set_option(ldap.OPT_X_SASL_NOCANON, ldap.OPT_ON) - - if start_tls: - self.conn.start_tls_s() - - def __str__(self): - return self.host + ":" + str(self.port) - - def do_bind(self, dm_password="", autobind=AUTOBIND_AUTO): - if dm_password: - self.simple_bind(bind_dn=DIRMAN_DN, bind_password=dm_password) - return - if autobind != AUTOBIND_DISABLED and os.getegid() == 0 and self.ldapi: - try: - # autobind - self.external_bind() - return - except errors.NotFound: - if autobind == AUTOBIND_ENABLED: - # autobind was required and failed, raise - # exception that it failed - raise - - #fall back - self.gssapi_bind() - - def modify_s(self, dn, modlist): - # FIXME: for backwards compatibility only - assert isinstance(dn, DN) - dn = str(dn) - modlist = [(a, self.encode(b), self.encode(c)) for a, b, c in modlist] - return self.conn.modify_s(dn, modlist) diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py index f1ddc417b..508bfabdc 100644 --- a/ipaserver/dcerpc.py +++ b/ipaserver/dcerpc.py @@ -45,7 +45,7 @@ import random from cryptography.hazmat.primitives.ciphers import Cipher, algorithms from cryptography.hazmat.backends import default_backend import ldap as _ldap -from ipapython.ipaldap import IPAdmin +from ipapython import ipaldap from ipaserver.session import krbccache_dir, krbccache_prefix from dns import resolver, rdatatype from dns.exception import DNSException @@ -760,11 +760,12 @@ class DomainValidator(object): entries = None try: - conn = IPAdmin(host=host, - port=389, # query the AD DC - no_schema=True, - decode_attrs=False, - sasl_nocanon=True) + ldap_uri = ipaldap.get_ldap_uri(host) + 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 diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py index 350cb3c76..65fc462c7 100644 --- a/ipaserver/install/bindinstance.py +++ b/ipaserver/install/bindinstance.py @@ -237,11 +237,9 @@ def dns_container_exists(fqdn, suffix, dm_password=None, ldapi=False, realm=None try: # At install time we may need to use LDAPI to avoid chicken/egg # issues with SSL certs and truting CAs - if ldapi: - conn = ipaldap.IPAdmin(host=fqdn, ldapi=True, realm=realm) - else: - conn = ipaldap.IPAdmin(host=fqdn, port=636, cacert=CACERT) - + ldap_uri = ipaldap.get_ldap_uri(fqdn, 636, ldapi=ldapi, realm=realm, + cacert=CACERT) + conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT) conn.do_bind(dm_password, autobind=autobind) except ldap.SERVER_DOWN: raise RuntimeError('LDAP server on %s is not responding. Is IPA installed?' % fqdn) diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index e6a7e24f6..a39d11dd9 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -1497,9 +1497,11 @@ def replica_ca_install_check(config): objectclass = 'ipaObject' root_logger.debug('Checking if IPA schema is present in %s', ca_ldap_url) try: - with ipaldap.LDAPClient(ca_ldap_url, - start_tls=True, - force_schema_updates=False) as connection: + with ipaldap.LDAPClient( + ca_ldap_url, + start_tls=True, + cacert=config.dir + "/ca.cer", + force_schema_updates=False) as connection: connection.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=config.dirman_password) rschema = connection.schema diff --git a/ipaserver/install/dnskeysyncinstance.py b/ipaserver/install/dnskeysyncinstance.py index f39787937..1ca6c7df3 100644 --- a/ipaserver/install/dnskeysyncinstance.py +++ b/ipaserver/install/dnskeysyncinstance.py @@ -41,10 +41,9 @@ def dnssec_container_exists(fqdn, suffix, dm_password=None, ldapi=False, try: # At install time we may need to use LDAPI to avoid chicken/egg # issues with SSL certs and truting CAs - if ldapi: - conn = ipaldap.IPAdmin(host=fqdn, ldapi=True, realm=realm) - else: - conn = ipaldap.IPAdmin(host=fqdn, port=636, cacert=CACERT) + ldap_uri = ipaldap.get_ldap_uri(fqdn, 636, ldapi=ldapi, realm=realm, + cacert=CACERT) + conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT) conn.do_bind(dm_password, autobind=autobind) except ldap.SERVER_DOWN: diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py index d7456a666..174191223 100644 --- a/ipaserver/install/dogtaginstance.py +++ b/ipaserver/install/dogtaginstance.py @@ -397,7 +397,8 @@ class DogtagInstance(service.Service): conn = None try: - conn = ipaldap.IPAdmin(self.fqdn, ldapi=True, realm=self.realm) + ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=self.realm) + conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() entry_attrs = conn.get_entry(self.admin_dn, ['usercertificate']) @@ -466,9 +467,8 @@ class DogtagInstance(service.Service): self.__add_admin_to_group(group) # Now wait until the other server gets replicated this data - master_conn = ipaldap.IPAdmin(self.master_host, - port=389, - protocol='ldap') + ldap_uri = ipaldap.get_ldap_uri(self.master_host) + master_conn = ipaldap.LDAPClient(ldap_uri) master_conn.gssapi_bind() replication.wait_for_entry(master_conn, entry) del master_conn diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index 773880b23..9c88b4936 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -168,7 +168,8 @@ def create_ds_user(): def get_domain_level(api=api): - conn = ipaldap.IPAdmin(ldapi=True, realm=api.env.realm) + 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'), @@ -411,12 +412,13 @@ class DsInstance(service.Service): def __setup_replica(self): - replication.enable_replication_version_checking(self.fqdn, + replication.enable_replication_version_checking( self.realm, self.dm_password) # Always connect to self over ldapi - conn = ipaldap.IPAdmin(self.fqdn, ldapi=True, realm=self.realm) + ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=self.realm) + conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() repl = replication.ReplicationManager(self.realm, self.fqdn, @@ -657,7 +659,8 @@ class DsInstance(service.Service): dn = DN(('cn', 'IPA install %s' % self.sub_dict["TIME"]), ('cn', 'memberof task'), ('cn', 'tasks'), ('cn', 'config')) root_logger.debug("Waiting for memberof task to complete.") - conn = ipaldap.IPAdmin(self.fqdn) + 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) @@ -793,7 +796,8 @@ class DsInstance(service.Service): self.nickname, self.principal, dsdb.passwd_fname, 'restart_dirsrv %s' % self.serverid) - conn = ipaldap.IPAdmin(self.fqdn) + 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) @@ -830,7 +834,8 @@ class DsInstance(service.Service): subject_base=self.subject_base) trust_flags = dict(reversed(dsdb.list_certs())) - conn = ipaldap.IPAdmin(self.fqdn) + 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) @@ -854,7 +859,8 @@ class DsInstance(service.Service): dsdb = certs.CertDB(self.realm, nssdir=dirname, subject_base=self.subject_base) - conn = ipaldap.IPAdmin(self.fqdn) + 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) @@ -1257,7 +1263,8 @@ class DsInstance(service.Service): db.create_pin_file() # Connect to self over ldapi as Directory Manager and configure SSL - conn = ipaldap.IPAdmin(self.fqdn, ldapi=True, realm=self.realm) + ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=self.realm) + conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() mod = [(ldap.MOD_REPLACE, "nsSSLClientAuth", "allowed"), diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py index def5e5856..6fc18706b 100644 --- a/ipaserver/install/ipa_backup.py +++ b/ipaserver/install/ipa_backup.py @@ -356,10 +356,8 @@ class Backup(admintool.AdminTool): if self._conn is not None: return self._conn - self._conn = ipaldap.IPAdmin(host=api.env.host, - ldapi=True, - protocol='ldapi', - realm=api.env.realm) + ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) + self._conn = ipaldap.LDAPClient(ldap_uri) try: self._conn.external_bind() diff --git a/ipaserver/install/ipa_replica_prepare.py b/ipaserver/install/ipa_replica_prepare.py index 2eef5fe43..00e971c8e 100644 --- a/ipaserver/install/ipa_replica_prepare.py +++ b/ipaserver/install/ipa_replica_prepare.py @@ -357,7 +357,8 @@ class ReplicaPrepare(admintool.AdminTool): self.log.info("Preparing replica for %s from %s", self.replica_fqdn, api.env.host) - enable_replication_version_checking(api.env.host, api.env.realm, + enable_replication_version_checking( + api.env.realm, self.dirman_password) self.top_dir = tempfile.mkdtemp("ipa") diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py index ea69cc713..21403afcf 100644 --- a/ipaserver/install/ipa_restore.py +++ b/ipaserver/install/ipa_restore.py @@ -435,10 +435,8 @@ class Restore(admintool.AdminTool): if self._conn is not None: return self._conn - self._conn = ipaldap.IPAdmin(host=api.env.host, - ldapi=True, - protocol='ldapi', - realm=api.env.realm) + ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) + self._conn = ipaldap.LDAPClient(ldap_uri) try: self._conn.external_bind() diff --git a/ipaserver/install/ldapupdate.py b/ipaserver/install/ldapupdate.py index 5e8d44de3..de03856d5 100644 --- a/ipaserver/install/ldapupdate.py +++ b/ipaserver/install/ldapupdate.py @@ -53,10 +53,8 @@ UPDATE_SEARCH_TIME_LIMIT = 30 # seconds def connect(ldapi=False, realm=None, fqdn=None, dm_password=None): """Create a connection for updates""" - if ldapi: - conn = ipaldap.IPAdmin(ldapi=True, realm=realm, decode_attrs=False) - else: - conn = ipaldap.IPAdmin(fqdn, ldapi=False, realm=realm, decode_attrs=False) + ldap_uri = ipaldap.get_ldap_uri(fqdn, ldapi=ldapi, realm=realm) + conn = ipaldap.LDAPClient(ldap_uri, decode_attrs=False) try: if dm_password: conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, diff --git a/ipaserver/install/plugins/fix_replica_agreements.py b/ipaserver/install/plugins/fix_replica_agreements.py index 321ddc636..3840660f8 100644 --- a/ipaserver/install/plugins/fix_replica_agreements.py +++ b/ipaserver/install/plugins/fix_replica_agreements.py @@ -35,7 +35,7 @@ class update_replica_attribute_lists(Updater): """ def execute(self, **options): - # We need an IPAdmin connection to the backend + # We need an LDAPClient connection to the backend self.log.debug("Start replication agreement exclude list update task") conn = self.api.Backend.ldap2 diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py index de7140530..2131840bb 100644 --- a/ipaserver/install/replication.py +++ b/ipaserver/install/replication.py @@ -109,13 +109,15 @@ def replica_conn_check(master_host, host_name, realm, check_ca, else: print("Connection check OK") -def enable_replication_version_checking(hostname, realm, dirman_passwd): + +def enable_replication_version_checking(realm, dirman_passwd): """ Check the replication version checking plugin. If it is not enabled then enable it and restart 389-ds. If it is enabled the do nothing. """ - conn = ipaldap.IPAdmin(hostname, realm=realm, ldapi=True) + ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=realm) + conn = ipaldap.LDAPClient(ldap_uri) if dirman_passwd: conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=dirman_passwd) @@ -206,17 +208,16 @@ class ReplicationManager(object): self.db_suffix = self.suffix self.agreement_name_format = "meTo%s" - # The caller is allowed to pass in an existing IPAdmin connection. + # The caller is allowed to pass in an existing LDAPClient connection. # Open a new one if not provided if conn is None: # If we are passed a password we'll use it as the DM password # otherwise we'll do a GSSAPI bind. - if starttls: - self.conn = ipaldap.IPAdmin( - hostname, port=port, cacert=CACERT, protocol='ldap', - start_tls=True) - else: - self.conn = ipaldap.IPAdmin(hostname, port=port, cacert=CACERT) + protocol = 'ldap' if starttls else None + ldap_uri = ipaldap.get_ldap_uri( + hostname, port, protocol=protocol, cacert=CACERT) + self.conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT, + start_tls=starttls) if dirman_passwd: self.conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=dirman_passwd) @@ -1006,9 +1007,9 @@ class ReplicationManager(object): local_port = r_port # note - there appears to be a bug in python-ldap - it does not # allow connections using two different CA certs - r_conn = ipaldap.IPAdmin( - r_hostname, port=r_port, cacert=CACERT, protocol='ldap', - start_tls=True) + ldap_uri = ipaldap.get_ldap_uri(r_hostname, r_port, cacert=CACERT, + protocol='ldap') + r_conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT, start_tls=True) if r_bindpw: r_conn.simple_bind(r_binddn, r_bindpw) @@ -1115,7 +1116,8 @@ class ReplicationManager(object): raise RuntimeError("Failed to start replication") def convert_to_gssapi_replication(self, r_hostname, r_binddn, r_bindpw): - r_conn = ipaldap.IPAdmin(r_hostname, port=PORT, cacert=CACERT) + ldap_uri = ipaldap.get_ldap_uri(r_hostname, PORT, cacert=CACERT) + r_conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT) if r_bindpw: r_conn.simple_bind(r_binddn, r_bindpw) else: @@ -1145,7 +1147,8 @@ class ReplicationManager(object): """ # note - there appears to be a bug in python-ldap - it does not # allow connections using two different CA certs - r_conn = ipaldap.IPAdmin(r_hostname, port=PORT, cacert=CACERT) + ldap_uri = ipaldap.get_ldap_uri(r_hostname, PORT, cacert=CACERT) + r_conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT) if r_bindpw: r_conn.simple_bind(r_binddn, r_bindpw) else: @@ -1603,7 +1606,8 @@ class ReplicationManager(object): def setup_promote_replication(self, r_hostname): # note - there appears to be a bug in python-ldap - it does not # allow connections using two different CA certs - r_conn = ipaldap.IPAdmin(r_hostname, port=389, protocol='ldap') + ldap_uri = ipaldap.get_ldap_uri(r_hostname) + r_conn = ipaldap.LDAPClient(ldap_uri) r_conn.gssapi_bind() # Setup the first half @@ -1739,7 +1743,8 @@ class CAReplicationManager(ReplicationManager): def __init__(self, realm, hostname): # Always connect to self over ldapi - conn = ipaldap.IPAdmin(hostname, ldapi=True, realm=realm) + ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=realm) + conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() super(CAReplicationManager, self).__init__( realm, hostname, None, port=DEFAULT_PORT, conn=conn) @@ -1751,7 +1756,8 @@ class CAReplicationManager(ReplicationManager): Assumes a promote replica with working GSSAPI for replication and unified DS instance. """ - r_conn = ipaldap.IPAdmin(r_hostname, port=389, protocol='ldap') + ldap_uri = ipaldap.get_ldap_uri(r_hostname) + r_conn = ipaldap.LDAPClient(ldap_uri) r_conn.gssapi_bind() # Setup the first half diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py index 68af0a307..aecf0f638 100644 --- a/ipaserver/install/server/install.py +++ b/ipaserver/install/server/install.py @@ -985,11 +985,8 @@ def uninstall_check(installer): raise ScriptError("Aborting uninstall operation.") try: - conn = ipaldap.IPAdmin( - api.env.host, - ldapi=True, - realm=api.env.realm - ) + ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) + conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() api.Backend.ldap2.connect(autobind=True) domain_level = dsinstance.get_domain_level(api) diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py index eafacb102..8458db6b7 100644 --- a/ipaserver/install/service.py +++ b/ipaserver/install/service.py @@ -30,6 +30,7 @@ from ipapython.ipa_log_manager import root_logger from ipalib import api, errors, certstore from ipaplatform import services from ipaplatform.paths import paths +from ipapython.ipaldap import LDAPClient # The service name as stored in cn=masters,cn=ipa,cn=etc. In the tuple @@ -144,7 +145,6 @@ class Service(object): self.start_tls = start_tls self.fqdn = socket.gethostname() - self.admin_conn = None if sstore: self.sstore = sstore @@ -156,34 +156,26 @@ class Service(object): self.principal = None self.dercert = None - def ldap_connect(self): - # If DM password is provided, we use it - # If autobind was requested, attempt autobind when root and ldapi - # If autobind was disabled or not succeeded, go with GSSAPI - # LDAPI can be used with either autobind or GSSAPI - # LDAPI requires realm to be set - try: - if self.ldapi: - if not self.realm: - raise errors.NotFound(reason="realm is missing for %s" % (self)) - conn = ipaldap.IPAdmin(ldapi=self.ldapi, realm=self.realm) - elif self.start_tls: - conn = ipaldap.IPAdmin(self.fqdn, port=389, protocol='ldap', - cacert=paths.IPA_CA_CRT, - start_tls=self.start_tls) - else: - conn = ipaldap.IPAdmin(self.fqdn, port=389) - - conn.do_bind(self.dm_password, autobind=self.autobind) - except Exception as e: - root_logger.debug("Could not connect to the Directory Server on %s: %s" % (self.fqdn, str(e))) - raise + @property + def admin_conn(self): + """ + alias for api.Backend.ldap2 + :returns: None when ldap2 is not connected, ldap2 connection otherwise + """ + conn = api.Backend.ldap2 + if conn.isconnected(): + return conn + return None - self.admin_conn = conn + def ldap_connect(self): + """connect to ldap with installer's limits""" + if not self.admin_conn: + api.Backend.ldap2.connect(size_limit=LDAPClient.size_limit, + time_limit=LDAPClient.time_limit) def ldap_disconnect(self): - self.admin_conn.unbind() - self.admin_conn = None + """close the api.Backend.ldap2 connection""" + api.Backend.ldap2.disconnect() def _ldap_mod(self, ldif, sub_dict=None, raise_on_err=True): pw_name = None diff --git a/ipatests/test_install/test_updates.py b/ipatests/test_install/test_updates.py index 553788d2a..57433c99f 100644 --- a/ipatests/test_install/test_updates.py +++ b/ipatests/test_install/test_updates.py @@ -63,7 +63,8 @@ class test_update(unittest.TestCase): else: raise nose.SkipTest("No directory manager password") self.updater = LDAPUpdate(dm_password=self.dm_password, sub_dict={}) - self.ld = ipaldap.IPAdmin(fqdn) + ldap_uri = ipaldap.get_ldap_uri(fqdn) + self.ld = ipaldap.LDAPClient(ldap_uri) self.ld.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) self.testdir = os.path.abspath(os.path.dirname(__file__)) diff --git a/ipatests/test_integration/host.py b/ipatests/test_integration/host.py index 8b9ebd5e8..121f91640 100644 --- a/ipatests/test_integration/host.py +++ b/ipatests/test_integration/host.py @@ -21,7 +21,7 @@ import pytest_multihost.host -from ipapython.ipaldap import IPAdmin +from ipapython import ipaldap class Host(pytest_multihost.host.Host): @@ -44,7 +44,8 @@ class Host(pytest_multihost.host.Host): """Return an LDAPClient authenticated to this host as directory manager """ self.log.info('Connecting to LDAP at %s', self.external_hostname) - ldap = IPAdmin(self.external_hostname) + ldap_uri = ipaldap.get_ldap_uri(self.external_hostname) + ldap = ipaldap.LDAPClient(ldap_uri) binddn = self.config.dirman_dn self.log.info('LDAP bind as %s' % binddn) ldap.simple_bind(binddn, self.config.dirman_password) |
