From 652d315b3e486abb0b51e02437cd0f1243425a6e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 6 Oct 2011 08:37:17 +0200 Subject: replica-prepare: anonymous binds may be disallowed Fixes: https://fedorahosted.org/freeipa/ticket/1900 --- install/tools/ipa-replica-install | 3 ++- install/tools/ipa-replica-manage | 3 ++- install/tools/ipa-replica-prepare | 51 +++++++++++++++++++++------------------ ipaserver/install/bindinstance.py | 23 +++++++++++++----- 4 files changed, 48 insertions(+), 32 deletions(-) diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install index 356e533ca..29c94fca0 100755 --- a/install/tools/ipa-replica-install +++ b/install/tools/ipa-replica-install @@ -220,7 +220,8 @@ def install_bind(config, options): def install_dns_records(config, options): if not bindinstance.dns_container_exists(config.master_host_name, - util.realm_to_suffix(config.realm_name)): + util.realm_to_suffix(config.realm_name), + dm_password=config.dirman_password): return # We have to force to connect to the remote master because we do this step diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage index 84cfd8f3e..e4ff7166e 100755 --- a/install/tools/ipa-replica-manage +++ b/install/tools/ipa-replica-manage @@ -328,7 +328,8 @@ def del_master(realm, hostname, options): # 5. And clean up the removed replica DNS entries if any. try: - if bindinstance.dns_container_exists(options.host, thisrepl.suffix): + if bindinstance.dns_container_exists(options.host, thisrepl.suffix, + dm_password=options.dirman_passwd): if options.dirman_passwd: api.Backend.ldap2.connect(bind_dn='cn=Directory Manager', bind_pw=options.dirman_passwd) diff --git a/install/tools/ipa-replica-prepare b/install/tools/ipa-replica-prepare index eb93bc851..6e98a2d0a 100755 --- a/install/tools/ipa-replica-prepare +++ b/install/tools/ipa-replica-prepare @@ -27,7 +27,7 @@ import krbV from ipapython import ipautil from ipaserver.install import bindinstance, dsinstance, installutils, certs -from ipaserver.install.bindinstance import add_zone, add_reverse_zone, add_fwd_rr, add_ptr_rr +from ipaserver.install.bindinstance import add_zone, add_reverse_zone, add_fwd_rr, add_ptr_rr, dns_container_exists from ipaserver.install.replication import enable_replication_version_checking from ipaserver.install.installutils import resolve_host from ipaserver.plugins.ldap2 import ldap2 @@ -246,14 +246,35 @@ def main(): if certs.ipa_self_signed_master() == False: sys.exit('A selfsign CA backend can only prepare on the original master') + # get the directory manager password + dirman_password = options.password + if not options.password: + try: + dirman_password = get_dirman_password() + except KeyboardInterrupt: + sys.exit(0) + if dirman_password is None: + sys.exit("\nDirectory Manager password required") + + # Try out the password + try: + conn = ldap2(shared_instance=False) + conn.connect(bind_dn='cn=directory manager', bind_pw=dirman_password) + conn.disconnect() + except errors.ACIError: + sys.exit("\nThe password provided is incorrect for LDAP server %s" % api.env.host) + except errors.LDAPError: + sys.exit("\nUnable to connect to LDAP server %s" % api.env.host) + try: installutils.verify_fqdn(replica_fqdn, system_name_check=False) except RuntimeError, e: msg = str(e) if msg.startswith('Unable to resolve host name'): if options.ip_address is None: - if bindinstance.dns_container_exists(api.env.host, - api.env.basedn): + if dns_container_exists(api.env.host, api.env.basedn, + dm_password=dirman_password, + ldapi=True, realm=api.env.realm): msg += '\nAdd the --ip-address argument to create a DNS entry.' sys.exit(msg) else: @@ -263,7 +284,9 @@ def main(): sys.exit(msg) if options.ip_address: - if not bindinstance.dns_container_exists(api.env.host, api.env.basedn): + if not dns_container_exists(api.env.host, api.env.basedn, + dm_password=dirman_password, + ldapi=True, realm=api.env.realm): print "You can't add a DNS record because DNS is not set up." sys.exit(1) if options.reverse_zone and not bindinstance.verify_reverse_zone(options.reverse_zone, options.ip_address): @@ -285,26 +308,6 @@ def main(): sys.exit(1) ds_dir = dsinstance.config_dirname(dsinstance.realm_to_serverid(api.env.realm)) - # get the directory manager password - dirman_password = options.password - if not options.password: - try: - dirman_password = get_dirman_password() - except KeyboardInterrupt: - sys.exit(0) - if dirman_password is None: - sys.exit("\nDirectory Manager password required") - - # Try out the password - try: - conn = ldap2(shared_instance=False) - conn.connect(bind_dn='cn=directory manager', bind_pw=dirman_password) - conn.disconnect() - except errors.ACIError: - sys.exit("\nThe password provided is incorrect for LDAP server %s" % api.env.host) - except errors.LDAPError: - sys.exit("\nUnable to connect to LDAP server %s" % api.env.host) - print "Preparing replica for %s from %s" % (replica_fqdn, api.env.host) enable_replication_version_checking(api.env.host, api.env.realm, dirman_password) diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py index f9bd3a84e..8dbcdbd98 100644 --- a/ipaserver/install/bindinstance.py +++ b/ipaserver/install/bindinstance.py @@ -79,7 +79,7 @@ def named_conf_exists(): return True return False -def dns_container_exists(fqdn, suffix): +def dns_container_exists(fqdn, suffix, dm_password=None, ldapi=False, realm=None): """ Test whether the dns container exists. """ @@ -89,20 +89,29 @@ def dns_container_exists(fqdn, suffix): Test whether the given object exists in LDAP. """ try: - server.search_ext_s(dn, ldap.SCOPE_BASE) + conn.search_ext_s(dn, ldap.SCOPE_BASE) except ldap.NO_SUCH_OBJECT: return False else: return True try: - server = ldap.initialize("ldap://" + ipautil.format_netloc(fqdn)) - server.simple_bind_s() + # 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=service.CACERT) + + if dm_password: + conn.do_simple_bind(bindpw=dm_password) + else: + conn.do_sasl_gssapi_bind() except ldap.SERVER_DOWN: raise RuntimeError('LDAP server on %s is not responding. Is IPA installed?' % fqdn) ret = object_exists("cn=dns,%s" % suffix) - server.unbind_s() + conn.unbind_s() return ret @@ -337,6 +346,7 @@ class BindInstance(service.Service): self.forwarders = None self.sub_dict = None self.reverse_zone = None + self.dm_password = dm_password if fstore: self.fstore = fstore @@ -387,7 +397,8 @@ class BindInstance(service.Service): if not installutils.record_in_hosts(self.ip_address, self.fqdn): installutils.add_record_to_hosts(self.ip_address, self.fqdn) - if not dns_container_exists(self.fqdn, self.suffix): + if not dns_container_exists(self.fqdn, self.suffix, realm=self.realm, + ldapi=True, dm_password=self.dm_password): self.step("adding DNS container", self.__setup_dns_container) if dns_zone_exists(self.domain): self.step("adding NS record to the zone", self.__add_self_ns) -- cgit