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
This commit is contained in:
Rob Crittenden 2010-09-17 21:23:08 -04:00
parent e648e03d0c
commit 74e5d8c2af
2 changed files with 66 additions and 13 deletions

View File

@ -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()

View File

@ -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)