diff options
author | Martin Kosek <mkosek@redhat.com> | 2012-01-20 08:30:40 +0100 |
---|---|---|
committer | Rob Crittenden <rcritten@redhat.com> | 2012-01-22 23:01:42 -0500 |
commit | 6141919fba30487e3c4eb19b0c87a10384fd9d20 (patch) | |
tree | 945367b213fc59bde5aa5db8cc32a2703c36f508 /ipaserver | |
parent | f7b4eb6a0918c0b73d4b98f47dcd76fa4e8072f5 (diff) | |
download | freeipa-6141919fba30487e3c4eb19b0c87a10384fd9d20.tar.gz freeipa-6141919fba30487e3c4eb19b0c87a10384fd9d20.tar.xz freeipa-6141919fba30487e3c4eb19b0c87a10384fd9d20.zip |
Fix ipa-server-install for dual NICs
A server may have 2 or more NICs and its hostname may thus resolve
to 2 and more forward addresses. IP address checks in install
scripts does not expect this setup and may fail or crash.
This script adds a support for multiple forward addresses for
a hostname. The install scripts do not crash now. When one IP
address is needed, user is asked to choose from all detected
server IP addresses.
https://fedorahosted.org/freeipa/ticket/2154
Diffstat (limited to 'ipaserver')
-rw-r--r-- | ipaserver/install/bindinstance.py | 16 | ||||
-rw-r--r-- | ipaserver/install/installutils.py | 66 |
2 files changed, 63 insertions, 19 deletions
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py index c7e382822..6e6c94111 100644 --- a/ipaserver/install/bindinstance.py +++ b/ipaserver/install/bindinstance.py @@ -197,7 +197,13 @@ def add_zone(name, zonemgr=None, dns_backup=None, ns_hostname=None, ns_ip_addres raise errors.NotFound("No IPA server with DNS support found!") ns_main = dns_masters.pop(0) ns_replicas = dns_masters - ns_ip_address = resolve_host(ns_main) + addresses = resolve_host(ns_main) + + if len(addresses) > 0: + # use the first address + ns_ip_address = addresses[0] + else: + ns_ip_address = None else: ns_main = ns_hostname ns_replicas = [] @@ -230,7 +236,13 @@ def add_reverse_zone(zone, ns_hostname=None, ns_ip_address=None, raise errors.NotFound("No IPA server with DNS support found!") ns_main = dns_masters.pop(0) ns_replicas = dns_masters - ns_ip_address = resolve_host(ns_main) + addresses = resolve_host(ns_main) + + if len(addresses) > 0: + # use the first address + ns_ip_address = addresses[0] + else: + ns_ip_address = None else: ns_main = ns_hostname ns_replicas = [] diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index e2cabf69b..94c1fabfb 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -90,27 +90,35 @@ def verify_dns_records(host_name, responses, resaddr, family): if family not in familykw.keys(): raise RuntimeError("Unknown faimily %s\n" % family) - rec = None + rec_list = [] for rsn in responses: - if rsn.dns_type == familykw[family]['dns_type']: - rec = rsn - break + if rsn.section == dnsclient.DNS_S_ANSWER and \ + rsn.dns_type == familykw[family]['dns_type']: + rec_list.append(rsn) - if rec == None: + if not rec_list: raise IOError(errno.ENOENT, "Warning: Hostname (%s) not found in DNS" % host_name) if family == 'ipv4': - familykw[family]['address'] = socket.inet_ntop(socket.AF_INET, - struct.pack('!L',rec.rdata.address)) + familykw[family]['address'] = [socket.inet_ntop(socket.AF_INET, + struct.pack('!L',rec.rdata.address)) \ + for rec in rec_list] else: - familykw[family]['address'] = socket.inet_ntop(socket.AF_INET6, - struct.pack('!16B', *rec.rdata.address)) + familykw[family]['address'] = [socket.inet_ntop(socket.AF_INET6, + struct.pack('!16B', *rec.rdata.address)) \ + for rec in rec_list] # Check that DNS address is the same is address returned via standard glibc calls - dns_addr = netaddr.IPAddress(familykw[family]['address']) - if dns_addr.format() != resaddr: - raise RuntimeError("The network address %s does not match the DNS lookup %s. Check /etc/hosts and ensure that %s is the IP address for %s" % (dns_addr.format(), resaddr, dns_addr.format(), host_name)) + dns_addrs = [netaddr.IPAddress(addr) for addr in familykw[family]['address']] + dns_addr = None + for addr in dns_addrs: + if addr.format() == resaddr: + dns_addr = addr + break + + if dns_addr is None: + raise RuntimeError("Host address %s does not match any address in DNS lookup." % resaddr) rs = dnsclient.query(dns_addr.reverse_dns, dnsclient.DNS_C_IN, dnsclient.DNS_T_PTR) if len(rs) == 0: @@ -498,14 +506,19 @@ def resolve_host(host_name): try: addrinfos = socket.getaddrinfo(host_name, None, socket.AF_UNSPEC, socket.SOCK_STREAM) + + ip_list = [] + for ai in addrinfos: ip = ai[4][0] if ip == "127.0.0.1" or ip == "::1": raise HostnameLocalhost("The hostname resolves to the localhost address") - return addrinfos[0][4][0] - except: - return None + ip_list.append(ip) + + return ip_list + except socket.error: + return [] def get_host_name(no_host_dns): """ @@ -534,8 +547,27 @@ def get_server_ip_address(host_name, fstore, unattended, options): sys.exit(1) ip_add_to_hosts = False - if hostaddr is not None: - ip = ipautil.CheckedIPAddress(hostaddr, match_local=True) + + if len(hostaddr) > 1: + print >> sys.stderr, "The server hostname resolves to more than one address:" + for addr in hostaddr: + print >> sys.stderr, " %s" % addr + + if options.ip_address: + if str(options.ip_address) not in hostaddr: + print >> sys.stderr, "Address passed in --ip-address did not match any resolved" + print >> sys.stderr, "address!" + sys.exit(1) + print "Selected IP address:", str(options.ip_address) + ip = options.ip_address + else: + if unattended: + print >> sys.stderr, "Please use --ip-address option to specify the address" + sys.exit(1) + else: + ip = read_ip_address(host_name, fstore) + elif len(hostaddr) == 1: + ip = ipautil.CheckedIPAddress(hostaddr[0], match_local=True) else: # hostname is not resolvable ip = options.ip_address |