On Wed, 2011-10-12 at 23:38 -0400, Rob Crittenden wrote:
> Martin Kosek wrote:
> > This patch depends on my patch 140 (attached just to be sure).
> >
> > Do I understand it correctly that new proposed bind-dyndb-ldap option
> > ldap_hostname won't be needed?
> >
> > Martin
> 
> I think it would be a good idea to add it when it becomes available in 
> bind-dyndb-ldap.

I will create a tracking ticket if the current 2.1.3 ticket gets closed.

> 
> NACK on the patch though.
> 
> Two problems so far:
> 
> 1. If an installation error occurs after the hostname has been changed 
> it isn't reverted and the uninstaller needs to be run. This should 
> rollback like the client.

I think this is quite different. Client runs a whole uninstall()
procedure when the installation crashes. I see we have following options
here:
1) Run uninstall() when server installation crashes (not my favorite,
this would make the investigation of what went difficult)
2) Restore just hostname and /etc/sysconfig/network file when
installation crashes and leave other for --uninstall (thus create a bit
inconsistent state)
3) Leave it as is

> 
> 2. It isn't actually working:
> 
> # ipa-server-install -a password -p password --setup-dns --hostname 
> foo.testrelm
> 
> [ snip ]
> 
> Server host name [foo.testrelm]:
> 
> Warning: skipping DNS resolution of host foo.testrelm
> 
> Warning: hostname foo.testrelm does not match system hostname 
> doberman.greyoak.com.
> System hostname will be updated during the installation process
> to prevent service failures.
> 
> The domain name has been calculated based on the host name.
> 
> Please confirm the domain name [testrelm]:
> 
> Unable to resolve IP address for host name
> Please provide the IP address to be used for this host name: 192.168.186.9
> Adding [192.168.186.9 foo.testrelm] to your /etc/hosts file
> The host name foo.testrelm does not match the reverse lookup 
> doberman.greyoak.com for 192.168.186.9
> Please check your DNS or /etc/hosts file and restart the installation.
> 
> [root@doberman freeipa]# cat /etc/hosts
> 127.0.0.1   localhost localhost.localdomain localhost4 
> localhost4.localdomain4
> ::1         localhost localhost.localdomain localhost6 
> localhost6.localdomain6
> 192.168.186.9   doberman.greyoak.com doberman
> 192.168.186.9   foo.testrelm foo
> 
> /etc/hosts contained the doberman entry previously.
> 
> rob

I think you did not have my patch 140 applied, otherwise the
installation should crash. This bug was there all the time I think.

To fix that, I created a patch
freeipa-mkosek-148-check-etc-hosts-file-in-ipa-server-install.patch
improving /etc/hosts.

Please, check all three attached rebased patches. They should fix both
tickets 1923 and 1931.

Martin
>From 3892616864a51304c4a7bb2d8c0cae5da6d90529 Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Fri, 7 Oct 2011 14:23:20 +0200
Subject: [PATCH] Check hostname resolution sanity

Always check (even with --setup-dns or --no-host-dns) that if the
host name or ip address resolves, it resolves to sane value. Otherwise
report an error. Misconfigured /etc/hosts causing these errors could
harm the installation later.

https://fedorahosted.org/freeipa/ticket/1923
---
 install/tools/ipa-replica-prepare |    2 +-
 ipaserver/install/installutils.py |   14 +++++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/install/tools/ipa-replica-prepare b/install/tools/ipa-replica-prepare
index 6b7130be9df262aee80c5e17201492fc4be01891..74c6d09296adb85dc8f66db35b61a413aad113c5 100755
--- a/install/tools/ipa-replica-prepare
+++ b/install/tools/ipa-replica-prepare
@@ -269,7 +269,7 @@ def main():
         sys.exit("\nUnable to connect to LDAP server %s" % api.env.host)
 
     try:
-        installutils.verify_fqdn(replica_fqdn, system_name_check=False)
+        installutils.verify_fqdn(replica_fqdn, local_hostname=False)
     except BadHostError, e:
         msg = str(e)
         if isinstance(e, HostLookupError):
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 64d212282de5d54af71aa84fd1dba857ae60f519..a924e771a5e3d780a458b42337ba050d835dd7d8 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -129,7 +129,7 @@ def verify_dns_records(host_name, responses, resaddr, family):
         raise RuntimeError("The DNS forward record %s does not match the reverse address %s" % (rec.dns_name, rev.rdata.ptrdname))
 
 
-def verify_fqdn(host_name, no_host_dns=False, system_name_check=True):
+def verify_fqdn(host_name, no_host_dns=False, local_hostname=True):
     """
     Run fqdn checks for given host:
         - test hostname format
@@ -140,7 +140,7 @@ def verify_fqdn(host_name, no_host_dns=False, system_name_check=True):
 
     :param host_name: The host name to verify.
     :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.
+    :param local_hostname: If true, run additional checks for local hostnames
     """
     if len(host_name.split(".")) < 2 or host_name == "localhost.localdomain":
         raise BadHostError("Invalid hostname '%s', must be fully-qualified." % host_name)
@@ -151,7 +151,15 @@ def verify_fqdn(host_name, no_host_dns=False, system_name_check=True):
     if ipautil.valid_ip(host_name):
         raise BadHostError("IP address not allowed as a hostname")
 
-    if system_name_check:
+    if local_hostname:
+        try:
+            ex_name = socket.gethostbyaddr(host_name)
+            if host_name != ex_name[0]:
+                raise HostLookupError("The host name %s does not match the primary host name %s. "\
+                        "Please check /etc/hosts or DNS name resolution" % (host_name, ex_name[0]))
+        except socket.gaierror:
+            pass
+
         system_host_name = socket.gethostname()
         if not (host_name + '.').startswith(system_host_name + '.'):
             print "Warning: The host name '%s' does not match the system host name '%s'." % (host_name, system_host_name)
-- 
1.7.6.4

>From 8b58709e6ffb3d0b8ae4e5bf69fc4b646cd2a9b6 Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Thu, 13 Oct 2011 12:15:41 +0200
Subject: [PATCH] Check /etc/hosts file in ipa-server-install

There may already be a record in /etc/hosts for chosen IP address
which may not be detected under some circumstances. Make sure
that /etc/hosts is checked properly.

https://fedorahosted.org/freeipa/ticket/1923
---
 install/tools/ipa-server-install  |   22 ++++++++++++++++++++++
 ipaserver/install/bindinstance.py |    2 +-
 ipaserver/install/installutils.py |   28 +++++++++++++++++++---------
 3 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index 7839dbd9fd68cb16ec9ec1f8ea385f0feacb8f2e..d6560f819b97c25e78f71b2f12a7c82d7c1c2a55 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -779,11 +779,33 @@ def main():
 
         ip = options.ip_address
 
+    ip_add_to_hosts = False
     if ip is None:
         ip = read_ip_address(host_name, fstore)
         logging.debug("read ip_address: %s\n" % str(ip))
+        ip_add_to_hosts = True
+
     ip_address = str(ip)
 
+    # check /etc/hosts sanity, add a record when needed
+    hosts_record = record_in_hosts(ip_address)
+
+    if hosts_record is None:
+        if ip_add_to_hosts:
+            print "Adding ["+ip_address+" "+host_name+"] to your /etc/hosts file"
+            fstore.backup_file("/etc/hosts")
+            add_record_to_hosts(ip_address, host_name)
+    else:
+        primary_host = hosts_record[1][0]
+        if primary_host != host_name:
+            print >>sys.stderr, "Error: there is already a record in /etc/hosts for IP address %s:" \
+                    % ip_address
+            print >>sys.stderr, hosts_record[0], " ".join(hosts_record[1])
+            print >>sys.stderr, "Chosen hostname %s does not match configured canonical hostname %s" \
+                    % (host_name, primary_host)
+            print >>sys.stderr, "Please fix your /etc/hosts file and restart the installation."
+            return 1
+
     if options.reverse_zone and not bindinstance.verify_reverse_zone(options.reverse_zone, ip):
         sys.exit(1)
 
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
index 8dbcdbd983c4ea883c856bf629dcee9b216e542f..ddf5497708ab8598d9a01fa0e555dd1ced55953b 100644
--- a/ipaserver/install/bindinstance.py
+++ b/ipaserver/install/bindinstance.py
@@ -394,7 +394,7 @@ class BindInstance(service.Service):
         # get a connection to the DS
         self.ldap_connect()
 
-        if not installutils.record_in_hosts(self.ip_address, self.fqdn):
+        if installutils.record_in_hosts(self.ip_address, self.fqdn) is None:
             installutils.add_record_to_hosts(self.ip_address, self.fqdn)
 
         if not dns_container_exists(self.fqdn, self.suffix, realm=self.realm,
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index a924e771a5e3d780a458b42337ba050d835dd7d8..652ce10ec94ec11211b9e3369e36d7a237bf4837 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -208,7 +208,18 @@ def verify_fqdn(host_name, no_host_dns=False, local_hostname=True):
     else:
         print "Warning: Hostname (%s) not found in DNS" % host_name
 
-def record_in_hosts(ip, host_name, file="/etc/hosts"):
+def record_in_hosts(ip, host_name=None, file="/etc/hosts"):
+    """
+    Search record in /etc/hosts - static table lookup for hostnames
+
+    In case of match, returns a tuple of ip address and a list of
+    hostname aliases
+    When no record is matched, None is returned
+
+    :param ip: IP address
+    :param host_name: Optional hostname to search
+    :param file: Optional path to the lookup table
+    """
     hosts = open(file, 'r').readlines()
     for line in hosts:
         line = line.rstrip('\n')
@@ -222,13 +233,17 @@ def record_in_hosts(ip, host_name, file="/etc/hosts"):
 
             if hosts_ip != ip:
                 continue
-            if host_name in names:
-                return True
+            if host_name is not None:
+                if host_name in names:
+                    return (hosts_ip, names)
+                else:
+                    return None
+            return (hosts_ip, names)
         except IndexError:
             print "Warning: Erroneous line '%s' in %s" % (line, file)
             continue
 
-    return False
+    return None
 
 def add_record_to_hosts(ip, host_name, file="/etc/hosts"):
     hosts_fd = open(file, 'r+')
@@ -247,11 +262,6 @@ def read_ip_address(host_name, fstore):
         else:
             break
 
-    ip = str(ip_parsed)
-    print "Adding ["+ip+" "+host_name+"] to your /etc/hosts file"
-    fstore.backup_file("/etc/hosts")
-    add_record_to_hosts(ip, host_name)
-
     return ip_parsed
 
 def read_dns_forwarders():
-- 
1.7.6.4

>From ab6be7ec6f3ee672ac3d153d63ff819f13a60e65 Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Thu, 13 Oct 2011 12:16:15 +0200
Subject: [PATCH] Hostname used by IPA must be a system hostname

Make sure that the hostname IPA uses is a system hostname. If user
passes a non-system hostname, update the network settings and
system hostname in the same way that ipa-client-install does.

This step should prevent various services failures which may not
be ready to talk to IPA with non-system hostname.

https://fedorahosted.org/freeipa/ticket/1931
---
 install/tools/ipa-server-install          |   23 +++++++++++++++++++++++
 install/tools/man/ipa-server-install.1    |    2 +-
 ipa-client/ipa-install/ipa-client-install |    4 +++-
 ipaserver/install/installutils.py         |    5 -----
 4 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index d6560f819b97c25e78f71b2f12a7c82d7c1c2a55..76d5f2f5af656a1947da0a5d5d855a398e34ef37 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -524,6 +524,14 @@ def uninstall():
 
     ipaservices.knownservices.ipa.disable()
 
+    old_hostname = sstore.restore_state('network','hostname')
+    system_hostname = get_fqdn()
+    if old_hostname is not None and old_hostname != system_hostname:
+        try:
+            ipautil.run(['/bin/hostname', old_hostname])
+        except CalledProcessError, e:
+            print >>sys.stderr, "Failed to set this machine hostname back to %s (%s)." % (old_hostname, str(e))
+
     # Now for some sanity checking. Make sure everything was really
     # uninstalled.
     serverids = dsinstance.check_existing_installation()
@@ -751,6 +759,15 @@ def main():
     host_name = host_name.lower()
     logging.debug("will use host_name: %s\n" % host_name)
 
+    system_hostname = get_fqdn()
+    if host_name != system_hostname:
+        print >>sys.stderr
+        print >>sys.stderr, "Warning: hostname %s does not match system hostname %s." \
+                            % (host_name, system_hostname)
+        print >>sys.stderr, "System hostname will be updated during the installation process"
+        print >>sys.stderr, "to prevent service failures."
+        print >>sys.stderr
+
     if not options.domain_name:
         domain_name = read_domain_name(host_name[host_name.find(".")+1:], options.unattended)
         logging.debug("read domain_name: %s\n" % domain_name)
@@ -893,6 +910,12 @@ def main():
         print "Please wait until the prompt is returned."
         print ""
 
+    if host_name != system_hostname:
+        logging.debug("Chosen hostname (%s) differs from system hostname (%s) - change it" \
+                      % (host_name, system_hostname))
+        # configure /etc/sysconfig/network to contain the custom hostname
+        ipaservices.backup_and_replace_hostname(fstore, sstore, host_name)
+
     # Create DS group if it doesn't exist yet
     try:
         grp.getgrnam(dsinstance.DS_GROUP)
diff --git a/install/tools/man/ipa-server-install.1 b/install/tools/man/ipa-server-install.1
index f305723b1926851c007d0fd177e52baa51d927d6..a281711381e231fa9bacb021238cf0c36d88d194 100644
--- a/install/tools/man/ipa-server-install.1
+++ b/install/tools/man/ipa-server-install.1
@@ -42,7 +42,7 @@ The kerberos master password (normally autogenerated)
 The password for the IPA admin user
 .TP
 \fB\-\-hostname\fR=\fIHOST_NAME\fR
-The fully\-qualified DNS name of this server
+The fully\-qualified DNS name of this server. If the hostname does not match system hostname, the system hostname will be updated accordingly to prevent service failures.
 .TP
 \fB\-\-ip\-address\fR=\fIIP_ADDRESS\fR
 The IP address of this server. If this address does not match the address the host resolves to and --setup-dns is not selected the installation will fail.
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index 969dc9b0faa5e131f1e9199325bdf2350157ab8a..62de4f8e127cdb0cde1d458ce2047dc252bd01ec 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -894,8 +894,10 @@ def install(options, env, fstore, statestore):
     if not options.unattended and not user_input("Continue to configure the system with these values?", False):
         return CLIENT_INSTALL_ERROR
 
-    if options.hostname:
+    if options.hostname and not options.on_master:
         # configure /etc/sysconfig/network to contain the hostname we set.
+        # skip this step when run by ipa-server-install as it always configures
+        # hostname if different from system hostname
         ipaservices.backup_and_replace_hostname(fstore, statestore, options.hostname)
 
     if not options.unattended:
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 652ce10ec94ec11211b9e3369e36d7a237bf4837..5cfc8f0376e25d9eb25206d54ac5bbea47aca9b2 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -160,11 +160,6 @@ def verify_fqdn(host_name, no_host_dns=False, local_hostname=True):
         except socket.gaierror:
             pass
 
-        system_host_name = socket.gethostname()
-        if not (host_name + '.').startswith(system_host_name + '.'):
-            print "Warning: The host name '%s' does not match the system host name '%s'." % (host_name, system_host_name)
-            print "         Some services may not work properly."
-
     if no_host_dns:
         print "Warning: skipping DNS resolution of host", host_name
         return
-- 
1.7.6.4

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to