Better distinguish between when DNS discovery works and search more domains.

Passing domain and server on the command-line used to be considered as DNS autodiscovery worked. This was problematic if there was in fact no SRV records because krb5.conf would be configured without a specific KDC causing all Kerberos ops to fail.

Now if you pass in a domain/server it still tries to see if they are discoverable and if so won't hardcode a server, but will fall back to doing so if necessary.

Also be a lot more aggressive on looking for the SRV records. Use the search and domain values from /etc/resolv.conf on the chance that the SRV records aren't in the domain of the hostname of the machine.

An example of this would be if your laptop is in dhcp.example.com and your company's SRV records are in corp.example.com. Searching dhcp.example.com and example.com won't find the SRV records but the user is likely to have corp.redhat.com in the search list, at least.

rob
>From 04f31efc4d98259cd4511dbe7d0ff6fd7f92d2b8 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcrit...@redhat.com>
Date: Fri, 17 Sep 2010 21:23:08 -0400
Subject: [PATCH] Better distinguish between when DNS discovery works and search more domains.

Passing domain and server on the command-line used to be considered as
DNS autodiscovery worked. This was problematic if there was in fact no
SRV records because krb5.conf would be configured without a specific KDC
causing all Kerberos ops to fail.

Now if you pass in a domain/server it still tries to see if they are
discoverable and if so won't hardcode a server, but will fall back to doing
so if necessary.

Also be a lot more aggressive on looking for the SRV records. Use the
search and domain values from /etc/resolv.conf on the chance that the
SRV records aren't in the domain of the hostname of the machine.

An example of this would be if your laptop is in dhcp.example.com and
your company's SRV records are in corp.example.com. Searching
dhcp.example.com and example.com won't find the SRV records but the user
is likely to have corp.redhat.com in the search list, at least.

ticket 234
---
 ipa-client/ipa-install/ipa-client-install |    9 ++--
 ipa-client/ipaclient/ipadiscovery.py      |   70 +++++++++++++++++++++++++----
 2 files changed, 66 insertions(+), 13 deletions(-)

diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index 5542f44..7e52b75 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -491,7 +491,7 @@ def configure_sssd_conf(fstore, cli_domain, cli_server, options):
 def main():
     options = parse_options()
     logging_setup(options)
-    dnsok = True
+    dnsok = False
     env={"PATH":"/bin:/sbin:/usr/kerberos/bin:/usr/kerberos/sbin:/usr/bin:/usr/sbin"}
 
     global fstore
@@ -518,7 +518,7 @@ def main():
     # Create the discovery instance
     ds = ipaclient.ipadiscovery.IPADiscovery()
 
-    ret = ds.search(domain=options.domain, server=options.server)
+    ret = ds.search()
     if ret == -10:
         print "Can't get the fully qualified name of this host"
         print "Please check that the client is properly configured"
@@ -532,13 +532,12 @@ def main():
         else:
             print "DNS discovery failed to determine your DNS domain"
             cli_domain = user_input("Please provide the domain name of your IPA server (ex: example.com)", allow_empty = False)
-        ret = ds.search(domain=cli_domain, server=options.server)
+        ret = ds.search(domain=cli_domain)
     if not cli_domain:
         if ds.getDomainName():
             cli_domain = ds.getDomainName()
 
     if ret == -2 or not ds.getServerName():
-        dnsok = False
         logging.debug("IPA Server not found")
         if options.server:
             cli_server = options.server
@@ -548,6 +547,8 @@ def main():
             print "DNS discovery failed to find the IPA Server"
             cli_server = user_input("Please provide your IPA server name (ex: ipa.example.com)", allow_empty = False)
         ret = ds.search(domain=cli_domain, server=cli_server)
+    else:
+        dnsok = True
     if not cli_server:
         if ds.getServerName():
             cli_server = ds.getServerName()
diff --git a/ipa-client/ipaclient/ipadiscovery.py b/ipa-client/ipaclient/ipadiscovery.py
index 45d5bd3..2187363 100644
--- a/ipa-client/ipaclient/ipadiscovery.py
+++ b/ipa-client/ipaclient/ipadiscovery.py
@@ -31,6 +31,31 @@ class IPADiscovery:
         self.server = None
         self.basedn = None
 
+    def __get_resolver_domains(self):
+        """
+        Read /etc/resolv.conf and return all the domains found in domain and
+        search.
+
+        Returns a list
+        """
+        domains = []
+        domain = None
+        try:
+            fp = open('/etc/resolv.conf', 'r')
+            lines = fp.readlines()
+            fp.close()
+
+            for line in lines:
+                if line.lower().startswith('domain'):
+                    domain = line.split(None)[-1]
+                elif line.lower().startswith('search'):
+                    domains = domains + line.split(None)[1:]
+        except:
+            pass
+        if domain and not domain in domains:
+            domains = [domain] + domains
+        return domains
+
     def getServerName(self):
         return self.server
 
@@ -43,6 +68,27 @@ class IPADiscovery:
     def getBaseDN(self):
         return self.basedn
 
+    def check_domain(self, domain):
+        """
+        Given a domain search it for SRV records, breaking it down to search
+        all subdomains too.
+
+        Returns a tuple (server, domain) or (None,None) if a SRV record
+        isn't found.
+        """
+        server = None
+        while not server:
+            logging.debug("[ipadnssearchldap("+domain+")]")
+            server = self.ipadnssearchldap(domain)
+            if server:
+                return (server, domain)
+            else:
+                p = domain.find(".")
+                if p == -1: #no ldap server found and last component of the domain already tested
+                    return (None, None)
+                domain = domain[p+1:]
+        return (None, None)
+
     def search(self, domain = "", server = ""):
         hostname = ""
         qname = ""
@@ -66,16 +112,22 @@ class IPADiscovery:
                     return -1
                 domain = hostname[p+1:]
 
-                while not self.server:
-                    logging.debug("[ipadnssearchldap("+domain+")]")
-                    self.server = self.ipadnssearchldap(domain)
-                    if self.server:
+                # Get the list of domains from /etc/resolv.conf, we'll search
+                # them all. We search the domain of our hostname first though,
+                # even if that means searching it twice. This is to avoid the
+                # situation where domain isn't set in /etc/resolv.conf and
+                # the search list has the hostname domain not first. We could
+                # end up with the wrong SRV record.
+                domains = self.__get_resolver_domains()
+                domains = [domain] + domains
+                for domain in domains:
+                    (server, domain) = self.check_domain(domain)
+                    if server:
+                        self.server = server
                         self.domain = domain
-                    else:
-                        p = domain.find(".")
-                        if p == -1: #no ldap server found and last component of the domain already tested
-                            return -1
-                        domain = domain[p+1:]
+                        break
+                if not self.domain: #no ldap server found
+                    return -1
             else:
                 logging.debug("[ipadnssearchldap]")
                 self.server = self.ipadnssearchldap(domain)
-- 
1.7.2.1

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

Reply via email to