Currently, verify_fqdn() function raises RuntimeError for every problem with the hostname. This makes it difficult for tools like ipa-replica-prepare to behave differently for a subset of raised errors (for example to be able to create a DNS record for new replica when verify_fqdn() reports a lookup error).
Implement own exceptions for verify_fqdn() that they can be safely used to distinguish the error type. https://fedorahosted.org/freeipa/ticket/1899
>From e93a70794e93264ef82756e21e8149403a9fc754 Mon Sep 17 00:00:00 2001 From: Martin Kosek <[email protected]> Date: Tue, 4 Oct 2011 14:31:00 +0200 Subject: [PATCH] Improve ipa-replica-prepare DNS check Currently, verify_fqdn() function raises RuntimeError for every problem with the hostname. This makes it difficult for tools like ipa-replica-prepare to behave differently for a subset of raised errors (for example to be able to create a DNS record for new replica when verify_fqdn() reports a lookup error). Implement own exceptions for verify_fqdn() that they can be safely used to distinguish the error type. https://fedorahosted.org/freeipa/ticket/1899 --- install/tools/ipa-ca-install | 4 +- install/tools/ipa-replica-install | 4 +- install/tools/ipa-replica-prepare | 6 ++-- install/tools/ipa-server-install | 15 ++++--------- ipaserver/install/installutils.py | 41 +++++++++++++++++++++++++----------- 5 files changed, 40 insertions(+), 30 deletions(-) diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install index 37fa6269b91dcd1174225a93ac5974ddc04e5d3a..ad617200700124da07265531099656b7d4603fa3 100755 --- a/install/tools/ipa-ca-install +++ b/install/tools/ipa-ca-install @@ -30,7 +30,7 @@ from ipaserver.install import installutils, service from ipaserver.install import certs from ipaserver.install.installutils import HostnameLocalhost from ipaserver.install.installutils import ReplicaConfig, expand_replica_info, read_replica_info -from ipaserver.install.installutils import get_host_name +from ipaserver.install.installutils import get_host_name, BadHostError from ipaserver.install import dsinstance, cainstance from ipaserver.install.replication import replica_conn_check from ipapython import version @@ -117,7 +117,7 @@ def main(): config.dirman_password = dirman_password try: host = get_host_name(options.no_host_dns) - except RuntimeError, e: + except BadHostError, e: logging.error(str(e)) sys.exit(1) if config.host_name != host: diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install index 62380443afa228315ebe7c598fe0e5427c7afb93..c2a0de22323d559fa25f513b6297f40d9ae94e86 100755 --- a/install/tools/ipa-replica-install +++ b/install/tools/ipa-replica-install @@ -32,7 +32,7 @@ from ipaserver.install import bindinstance, httpinstance, ntpinstance, certs from ipaserver.install.replication import replica_conn_check from ipaserver.install.installutils import HostnameLocalhost, resolve_host from ipaserver.install.installutils import ReplicaConfig, expand_replica_info, read_replica_info -from ipaserver.install.installutils import get_host_name +from ipaserver.install.installutils import get_host_name, BadHostError from ipaserver.plugins.ldap2 import ldap2 from ipaserver.install import cainstance from ipapython import version @@ -328,7 +328,7 @@ def main(): config.dirman_password = dirman_password try: host = get_host_name(options.no_host_dns) - except RuntimeError, e: + except BadHostError, e: logging.error(str(e)) sys.exit(1) if config.host_name != host: diff --git a/install/tools/ipa-replica-prepare b/install/tools/ipa-replica-prepare index 05115ac3ccdfdca87960025811dc992c5d6ab530..714f465d120083c502e9a83238f3bad61be3b443 100755 --- a/install/tools/ipa-replica-prepare +++ b/install/tools/ipa-replica-prepare @@ -29,7 +29,7 @@ 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.replication import enable_replication_version_checking -from ipaserver.install.installutils import resolve_host +from ipaserver.install.installutils import resolve_host, BadHostError, HostLookupError from ipaserver.plugins.ldap2 import ldap2 from ipapython import version from ipapython.config import IPAOptionParser @@ -250,9 +250,9 @@ def main(): try: installutils.verify_fqdn(replica_fqdn, system_name_check=False) - except RuntimeError, e: + except BadHostError, e: msg = str(e) - if msg.startswith('Unable to resolve host name'): + if isinstance(e, HostLookupError): if options.ip_address is None: if bindinstance.dns_container_exists(api.env.host, api.env.basedn): diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install index 504d6af50f70278864dacf44cac9e4bbc832e069..e4484b77c27364feff03847323735920a6814823 100755 --- a/install/tools/ipa-server-install +++ b/install/tools/ipa-server-install @@ -368,15 +368,10 @@ def read_host_name(host_default,no_host_dns=False): print "" if host_default == "": host_default = "master.example.com" - while True: - host_name = user_input("Server host name", host_default, allow_empty = False) - print "" - try: - verify_fqdn(host_name,no_host_dns) - except Exception, e: - raise e - else: - break + host_name = user_input("Server host name", host_default, allow_empty = False) + print "" + verify_fqdn(host_name,no_host_dns) + return host_name def read_domain_name(domain_name, unattended): @@ -723,7 +718,7 @@ def main(): host_name = host_default else: host_name = read_host_name(host_default,options.no_host_dns) - except RuntimeError, e: + except BadHostError, e: sys.exit(str(e) + "\n") host_name = host_name.lower() diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index 44292fd4c303c0caa5d77e525dd1041095543b51..5772f1a4d16ea83406958dc32b005eab79e9f8b0 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -38,7 +38,19 @@ from ipapython import ipautil, dnsclient, sysrestore # Used to determine install status IPA_MODULES = ['httpd', 'ipa_kpasswd', 'dirsrv', 'pki-cad', 'pkids', 'install', 'krb5kdc', 'ntpd', 'named'] -class HostnameLocalhost(Exception): +class BadHostError(Exception): + pass + +class HostLookupError(BadHostError): + pass + +class HostForwardLookupError(HostLookupError): + pass + +class HostReverseLookupError(HostLookupError): + pass + +class HostnameLocalhost(HostLookupError): pass class ReplicaConfig: @@ -119,22 +131,25 @@ def verify_dns_records(host_name, responses, resaddr, family): def verify_fqdn(host_name, no_host_dns=False, system_name_check=True): """ - Verify that the given host name is fully-qualified. + Run fqdn checks for given host: + - test hostname format + - test that hostname is fully qualified + - test forward and reverse hostname DNS lookup - Raises `RuntimeError` if the host name is not fully-qualified. + Raises `BadHostError` or derived Exceptions if there is an error :param host_name: The host name to verify. - :param no_host_dns: If true, skip DNS resolution of the host name. + :param no_host_dns: If true, skip DNS resolution tests of the host name. :param system_name_check: If true, check if the host name matches the system host name. """ if len(host_name.split(".")) < 2 or host_name == "localhost.localdomain": - raise RuntimeError("Invalid hostname '%s', must be fully-qualified." % host_name) + raise BadHostError("Invalid hostname '%s', must be fully-qualified." % host_name) if host_name != host_name.lower(): - raise RuntimeError("Invalid hostname '%s', must be lower-case." % host_name) + raise BadHostError("Invalid hostname '%s', must be lower-case." % host_name) if ipautil.valid_ip(host_name): - raise RuntimeError("IP address not allowed as a hostname") + raise BadHostError("IP address not allowed as a hostname") if system_name_check: system_host_name = socket.gethostname() @@ -149,28 +164,28 @@ def verify_fqdn(host_name, no_host_dns=False, system_name_check=True): try: hostaddr = socket.getaddrinfo(host_name, None) except: - raise RuntimeError("Unable to resolve host name, check /etc/hosts or DNS name resolution") + raise HostForwardLookupError("Unable to resolve host name, check /etc/hosts or DNS name resolution") if len(hostaddr) == 0: - raise RuntimeError("Unable to resolve host name, check /etc/hosts or DNS name resolution") + raise HostForwardLookupError("Unable to resolve host name, check /etc/hosts or DNS name resolution") for a in hostaddr: if a[4][0] == '127.0.0.1' or a[4][0] == '::1': - raise RuntimeError("The IPA Server hostname must not resolve to localhost (%s). A routable IP address must be used. Check /etc/hosts to see if %s is an alias for %s" % (a[4][0], host_name, a[4][0])) + raise HostForwardLookupError("The IPA Server hostname must not resolve to localhost (%s). A routable IP address must be used. Check /etc/hosts to see if %s is an alias for %s" % (a[4][0], host_name, a[4][0])) try: resaddr = a[4][0] revname = socket.gethostbyaddr(a[4][0])[0] except: - raise RuntimeError("Unable to resolve the reverse ip address, check /etc/hosts or DNS name resolution") + raise HostReverseLookupError("Unable to resolve the reverse ip address, check /etc/hosts or DNS name resolution") if revname != host_name: - raise RuntimeError("The host name %s does not match the reverse lookup %s" % (host_name, revname)) + raise HostReverseLookupError("The host name %s does not match the reverse lookup %s" % (host_name, revname)) # Verify this is NOT a CNAME rs = dnsclient.query(host_name+".", dnsclient.DNS_C_IN, dnsclient.DNS_T_CNAME) if len(rs) != 0: for rsn in rs: if rsn.dns_type == dnsclient.DNS_T_CNAME: - raise RuntimeError("The IPA Server Hostname cannot be a CNAME, only A and AAAA names are allowed.") + raise HostReverseLookupError("The IPA Server Hostname cannot be a CNAME, only A and AAAA names are allowed.") # Verify that it is a DNS A or AAAA record rs = dnsclient.query(host_name+".", dnsclient.DNS_C_IN, dnsclient.DNS_T_A) -- 1.7.6.2
_______________________________________________ Freeipa-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/freeipa-devel
