summaryrefslogtreecommitdiffstats
path: root/ipaserver
diff options
context:
space:
mode:
authorMartin Kosek <mkosek@redhat.com>2012-01-20 08:30:40 +0100
committerRob Crittenden <rcritten@redhat.com>2012-01-22 23:01:42 -0500
commit6141919fba30487e3c4eb19b0c87a10384fd9d20 (patch)
tree945367b213fc59bde5aa5db8cc32a2703c36f508 /ipaserver
parentf7b4eb6a0918c0b73d4b98f47dcd76fa4e8072f5 (diff)
downloadfreeipa-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.py16
-rw-r--r--ipaserver/install/installutils.py66
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