2007-08-16 17:00:16 -05:00
|
|
|
# Authors: Simo Sorce <ssorce@redhat.com>
|
|
|
|
#
|
|
|
|
# Copyright (C) 2007 Red Hat
|
|
|
|
# see file 'COPYING' for use and warranty information
|
|
|
|
#
|
2010-12-09 06:59:11 -06:00
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
2007-08-16 17:00:16 -05:00
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
2010-12-09 06:59:11 -06:00
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2007-08-16 17:00:16 -05:00
|
|
|
#
|
|
|
|
|
|
|
|
import socket
|
2011-02-21 14:32:21 -06:00
|
|
|
import os
|
2011-11-15 13:39:31 -06:00
|
|
|
from ipapython.ipa_log_manager import *
|
2011-02-21 14:32:21 -06:00
|
|
|
import tempfile
|
2007-08-16 17:00:16 -05:00
|
|
|
import ldap
|
|
|
|
from ldap import LDAPError
|
2012-05-11 07:38:09 -05:00
|
|
|
from dns import resolver, rdatatype
|
|
|
|
from dns.exception import DNSException
|
|
|
|
|
2011-09-30 09:52:30 -05:00
|
|
|
from ipapython.ipautil import run, CalledProcessError, valid_ip, get_ipa_basedn, \
|
2012-05-11 07:38:09 -05:00
|
|
|
realm_to_suffix, format_netloc
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2011-07-06 09:30:24 -05:00
|
|
|
|
|
|
|
NOT_FQDN = -1
|
|
|
|
NO_LDAP_SERVER = -2
|
|
|
|
REALM_NOT_FOUND = -3
|
|
|
|
NOT_IPA_SERVER = -4
|
2011-09-28 15:31:38 -05:00
|
|
|
NO_ACCESS_TO_LDAP = -5
|
2011-07-06 09:30:24 -05:00
|
|
|
BAD_HOST_CONFIG = -10
|
2011-09-28 15:31:38 -05:00
|
|
|
UNKNOWN_ERROR = -15
|
2011-07-06 09:30:24 -05:00
|
|
|
|
2012-06-13 10:44:06 -05:00
|
|
|
error_names = {
|
|
|
|
0: 'Success',
|
|
|
|
NOT_FQDN: 'NOT_FQDN',
|
|
|
|
NO_LDAP_SERVER: 'NO_LDAP_SERVER',
|
|
|
|
REALM_NOT_FOUND: 'REALM_NOT_FOUND',
|
|
|
|
NOT_IPA_SERVER: 'NOT_IPA_SERVER',
|
|
|
|
NO_ACCESS_TO_LDAP: 'NO_ACCESS_TO_LDAP',
|
|
|
|
BAD_HOST_CONFIG: 'BAD_HOST_CONFIG',
|
|
|
|
UNKNOWN_ERROR: 'UNKNOWN_ERROR',
|
|
|
|
}
|
|
|
|
|
|
|
|
class IPADiscovery(object):
|
2007-08-16 17:00:16 -05:00
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
self.realm = None
|
|
|
|
self.domain = None
|
|
|
|
self.server = None
|
2007-08-30 18:40:54 -05:00
|
|
|
self.basedn = None
|
2007-08-16 17:00:16 -05:00
|
|
|
|
2012-06-13 10:44:06 -05:00
|
|
|
self.realm_source = None
|
|
|
|
self.domain_source = None
|
|
|
|
self.server_source = None
|
|
|
|
self.basedn_source = None
|
|
|
|
|
2010-09-17 20:23:08 -05:00
|
|
|
def __get_resolver_domains(self):
|
|
|
|
"""
|
|
|
|
Read /etc/resolv.conf and return all the domains found in domain and
|
|
|
|
search.
|
|
|
|
|
2012-06-13 10:44:06 -05:00
|
|
|
Returns a list of (domain, info) pairs. The info contains a reason why
|
|
|
|
the domain is returned.
|
2010-09-17 20:23:08 -05:00
|
|
|
"""
|
|
|
|
domains = []
|
|
|
|
domain = None
|
|
|
|
try:
|
|
|
|
fp = open('/etc/resolv.conf', 'r')
|
|
|
|
lines = fp.readlines()
|
|
|
|
fp.close()
|
|
|
|
|
|
|
|
for line in lines:
|
|
|
|
if line.lower().startswith('domain'):
|
2012-06-13 10:44:06 -05:00
|
|
|
domain = (line.split()[-1],
|
|
|
|
'local domain from /etc/resolv.conf')
|
2010-09-17 20:23:08 -05:00
|
|
|
elif line.lower().startswith('search'):
|
2012-06-13 10:44:06 -05:00
|
|
|
domains += [(d, 'search domain from /etc/resolv.conf') for
|
|
|
|
d in line.split()[1:]]
|
2010-09-17 20:23:08 -05:00
|
|
|
except:
|
|
|
|
pass
|
2012-06-13 10:44:06 -05:00
|
|
|
if domain:
|
2010-09-17 20:23:08 -05:00
|
|
|
domains = [domain] + domains
|
|
|
|
return domains
|
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
def getServerName(self):
|
2008-03-05 15:33:12 -06:00
|
|
|
return self.server
|
2007-08-16 17:00:16 -05:00
|
|
|
|
|
|
|
def getDomainName(self):
|
2008-03-05 15:33:12 -06:00
|
|
|
return self.domain
|
2007-08-16 17:00:16 -05:00
|
|
|
|
|
|
|
def getRealmName(self):
|
2008-03-05 15:33:12 -06:00
|
|
|
return self.realm
|
2007-08-16 17:00:16 -05:00
|
|
|
|
2011-03-21 08:50:05 -05:00
|
|
|
def getKDCName(self):
|
|
|
|
return self.kdc
|
|
|
|
|
2007-08-30 18:40:54 -05:00
|
|
|
def getBaseDN(self):
|
2008-03-05 15:33:12 -06:00
|
|
|
return self.basedn
|
2007-08-30 18:40:54 -05:00
|
|
|
|
2012-06-13 10:44:06 -05:00
|
|
|
def check_domain(self, domain, tried, reason):
|
2010-09-17 20:23:08 -05:00
|
|
|
"""
|
|
|
|
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.
|
2012-06-13 10:44:06 -05:00
|
|
|
|
|
|
|
:param tried: A set of domains that were tried already
|
|
|
|
:param reason: Reason this domain is searched (included in the log)
|
2010-09-17 20:23:08 -05:00
|
|
|
"""
|
|
|
|
server = None
|
2012-06-13 10:44:06 -05:00
|
|
|
root_logger.debug('Start searching for LDAP SRV record in "%s" (%s) ' +
|
|
|
|
'and its sub-domains', domain, reason)
|
2010-09-17 20:23:08 -05:00
|
|
|
while not server:
|
2012-06-13 10:44:06 -05:00
|
|
|
if domain in tried:
|
|
|
|
root_logger.debug("Already searched %s; skipping", domain)
|
|
|
|
break
|
|
|
|
tried.add(domain)
|
|
|
|
|
2012-05-11 07:38:09 -05:00
|
|
|
server = self.ipadns_search_srv(domain, '_ldap._tcp', 389)
|
2010-09-17 20:23:08 -05:00
|
|
|
if server:
|
2012-05-11 07:38:09 -05:00
|
|
|
return (server[0], domain)
|
2010-09-17 20:23:08 -05:00
|
|
|
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)
|
|
|
|
|
2011-07-06 09:30:24 -05:00
|
|
|
def search(self, domain = "", server = "", hostname=None):
|
2012-06-13 10:44:06 -05:00
|
|
|
root_logger.debug("[IPA Discovery]")
|
|
|
|
root_logger.debug(
|
|
|
|
'Starting IPA discovery with domain=%s, server=%s, hostname=%s',
|
|
|
|
domain, server, hostname)
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2012-07-03 16:37:22 -05:00
|
|
|
if type(server) in (list, tuple):
|
|
|
|
server = server[0]
|
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
if not server:
|
|
|
|
|
|
|
|
if not domain: #domain not provided do full DNS discovery
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
# get the local host name
|
|
|
|
if not hostname:
|
2011-07-06 09:30:24 -05:00
|
|
|
hostname = socket.getfqdn()
|
2012-06-13 10:44:06 -05:00
|
|
|
root_logger.debug('Hostname: %s', hostname)
|
2011-07-06 09:30:24 -05:00
|
|
|
if not hostname:
|
|
|
|
return BAD_HOST_CONFIG
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2011-07-25 10:14:01 -05:00
|
|
|
if valid_ip(hostname):
|
|
|
|
return NOT_FQDN
|
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
# first, check for an LDAP server for the local domain
|
|
|
|
p = hostname.find(".")
|
|
|
|
if p == -1: #no domain name
|
2011-07-06 09:30:24 -05:00
|
|
|
return NOT_FQDN
|
2007-08-16 17:00:16 -05:00
|
|
|
domain = hostname[p+1:]
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2010-09-17 20:23:08 -05:00
|
|
|
# Get the list of domains from /etc/resolv.conf, we'll search
|
2012-06-13 10:44:06 -05:00
|
|
|
# them all. We search the domain of our hostname first though.
|
|
|
|
# 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.
|
2010-09-17 20:23:08 -05:00
|
|
|
domains = self.__get_resolver_domains()
|
2012-06-13 10:44:06 -05:00
|
|
|
domains = [(domain, 'domain of the hostname')] + domains
|
|
|
|
tried = set()
|
|
|
|
for domain, reason in domains:
|
|
|
|
server, domain = self.check_domain(domain, tried, reason)
|
2010-09-17 20:23:08 -05:00
|
|
|
if server:
|
|
|
|
self.server = server
|
2007-08-16 17:00:16 -05:00
|
|
|
self.domain = domain
|
2012-06-13 10:44:06 -05:00
|
|
|
self.server_source = self.domain_source = (
|
|
|
|
'Discovered LDAP SRV records from %s (%s)' %
|
|
|
|
(domain, reason))
|
2010-09-17 20:23:08 -05:00
|
|
|
break
|
|
|
|
if not self.domain: #no ldap server found
|
2012-06-13 10:44:06 -05:00
|
|
|
root_logger.debug('No LDAP server found')
|
2011-07-06 09:30:24 -05:00
|
|
|
return NO_LDAP_SERVER
|
2007-08-16 17:00:16 -05:00
|
|
|
else:
|
2012-05-11 07:38:09 -05:00
|
|
|
root_logger.debug("Search for LDAP SRV record in %s", domain)
|
|
|
|
server = self.ipadns_search_srv(domain, '_ldap._tcp', 389)
|
|
|
|
if server:
|
|
|
|
self.server = server[0]
|
2007-08-16 17:00:16 -05:00
|
|
|
self.domain = domain
|
2012-06-13 10:44:06 -05:00
|
|
|
self.server_source = self.domain_source = (
|
|
|
|
'Discovered LDAP SRV records from %s' % domain)
|
2007-08-16 17:00:16 -05:00
|
|
|
else:
|
2012-05-11 07:38:09 -05:00
|
|
|
self.server = None
|
2012-06-13 10:44:06 -05:00
|
|
|
root_logger.debug('No LDAP server found')
|
2011-07-06 09:30:24 -05:00
|
|
|
return NO_LDAP_SERVER
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2012-06-13 10:44:06 -05:00
|
|
|
else:
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2012-06-13 10:44:06 -05:00
|
|
|
root_logger.debug("Server and domain forced")
|
2007-08-16 17:00:16 -05:00
|
|
|
self.domain = domain
|
|
|
|
self.server = server
|
2012-06-13 10:44:06 -05:00
|
|
|
self.domain_source = self.server_source = 'Forced'
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2011-03-21 08:50:05 -05:00
|
|
|
#search for kerberos
|
2012-06-13 10:44:06 -05:00
|
|
|
root_logger.debug("[Kerberos realm search]")
|
|
|
|
krb_realm, kdc = self.ipadnssearchkrb(self.domain)
|
|
|
|
if not server and not krb_realm:
|
2011-07-06 09:30:24 -05:00
|
|
|
return REALM_NOT_FOUND
|
2011-03-21 08:50:05 -05:00
|
|
|
|
2012-06-13 10:44:06 -05:00
|
|
|
self.realm = krb_realm
|
|
|
|
self.kdc = kdc
|
|
|
|
self.realm_source = self.kdc_source = (
|
|
|
|
'Discovered Kerberos DNS records from %s' % self.domain)
|
2011-03-21 08:50:05 -05:00
|
|
|
|
2012-06-13 10:44:06 -05:00
|
|
|
root_logger.debug("[LDAP server check]")
|
|
|
|
root_logger.debug('Verifying that %s (realm %s) is an IPA server',
|
|
|
|
self.server, self.realm)
|
2011-12-07 06:40:46 -06:00
|
|
|
# We may have received multiple servers corresponding to the domain
|
|
|
|
# Iterate through all of those to check if it is IPA LDAP server
|
|
|
|
ldapret = [NOT_IPA_SERVER]
|
|
|
|
ldapaccess = True
|
2012-05-11 07:38:09 -05:00
|
|
|
if self.server:
|
2011-12-07 06:40:46 -06:00
|
|
|
# check ldap now
|
2012-05-11 07:38:09 -05:00
|
|
|
ldapret = self.ipacheckldap(self.server, self.realm)
|
2011-12-07 06:40:46 -06:00
|
|
|
|
|
|
|
if ldapret[0] == 0:
|
|
|
|
self.server = ldapret[1]
|
|
|
|
self.realm = ldapret[2]
|
2012-06-13 10:44:06 -05:00
|
|
|
self.server_source = self.realm_source = (
|
|
|
|
'Discovered from LDAP DNS records in %s' % self.server)
|
2012-05-11 07:38:09 -05:00
|
|
|
elif ldapret[0] == NO_ACCESS_TO_LDAP:
|
2011-12-07 06:40:46 -06:00
|
|
|
ldapaccess = False
|
|
|
|
|
2012-06-13 10:44:06 -05:00
|
|
|
# If one of LDAP servers checked rejects access (maybe anonymous
|
2011-12-07 06:40:46 -06:00
|
|
|
# bind is disabled), assume realm and basedn generated off domain.
|
|
|
|
# Note that in case ldapret[0] == 0 and ldapaccess == False (one of
|
|
|
|
# servers didn't provide access but another one succeeded), self.realm
|
|
|
|
# will be set already to a proper value above, self.basdn will be
|
|
|
|
# initialized during the LDAP check itself and we'll skip these two checks.
|
|
|
|
if not ldapaccess and self.realm is None:
|
2011-09-28 15:31:38 -05:00
|
|
|
# Assume realm is the same as domain.upper()
|
|
|
|
self.realm = self.domain.upper()
|
2012-06-13 10:44:06 -05:00
|
|
|
self.realm_source = 'Assumed same as domain'
|
|
|
|
root_logger.debug(
|
|
|
|
"Assuming realm is the same as domain: %s", self.realm)
|
2011-09-30 09:52:30 -05:00
|
|
|
|
2011-12-07 06:40:46 -06:00
|
|
|
if not ldapaccess and self.basedn is None:
|
2011-09-30 09:52:30 -05:00
|
|
|
# Generate suffix from realm
|
|
|
|
self.basedn = realm_to_suffix(self.realm)
|
2012-06-13 10:44:06 -05:00
|
|
|
self.basedn_source = 'Generated from Kerberos realm'
|
|
|
|
root_logger.debug("Generated basedn from realm: %s" % self.basedn)
|
|
|
|
|
|
|
|
root_logger.debug(
|
|
|
|
"Discovery result: %s; server=%s, domain=%s, kdc=%s, basedn=%s",
|
|
|
|
error_names.get(ldapret[0], ldapret[0]),
|
|
|
|
self.server, self.domain, self.kdc, self.basedn)
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2011-09-28 15:31:38 -05:00
|
|
|
return ldapret[0]
|
2007-08-16 17:00:16 -05:00
|
|
|
|
|
|
|
def ipacheckldap(self, thost, trealm):
|
2011-07-06 09:30:24 -05:00
|
|
|
"""
|
|
|
|
Given a host and kerberos realm verify that it is an IPA LDAP
|
|
|
|
server hosting the realm. The connection is an SSL connection
|
|
|
|
so the remote IPA CA cert must be available at
|
|
|
|
http://HOST/ipa/config/ca.crt
|
|
|
|
|
2011-09-28 15:31:38 -05:00
|
|
|
Returns a list [errno, host, realm] or an empty list on error.
|
|
|
|
Errno is an error number:
|
|
|
|
0 means all ok
|
|
|
|
1 means we could not check the info in LDAP (may happend when
|
2011-12-07 06:40:46 -06:00
|
|
|
anonymous binds are disabled)
|
2011-09-28 15:31:38 -05:00
|
|
|
2 means the server is certainly not an IPA server
|
2011-07-06 09:30:24 -05:00
|
|
|
"""
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
lrealms = []
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
i = 0
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2011-02-21 14:32:21 -06:00
|
|
|
# Get the CA certificate
|
|
|
|
try:
|
|
|
|
# Create TempDir
|
|
|
|
temp_ca_dir = tempfile.mkdtemp()
|
|
|
|
except OSError, e:
|
|
|
|
raise RuntimeError("Creating temporary directory failed: %s" % str(e))
|
|
|
|
|
|
|
|
try:
|
2011-10-12 03:55:08 -05:00
|
|
|
run(["/usr/bin/wget", "-O", "%s/ca.crt" % temp_ca_dir, "-T", "15", "-t", "2",
|
|
|
|
"http://%s/ipa/config/ca.crt" % format_netloc(thost)])
|
2011-02-21 14:32:21 -06:00
|
|
|
except CalledProcessError, e:
|
2012-06-13 10:44:06 -05:00
|
|
|
root_logger.debug('Retrieving CA from %s failed: %s', thost, str(e))
|
2011-09-28 15:31:38 -05:00
|
|
|
return [NOT_IPA_SERVER]
|
2011-02-21 14:32:21 -06:00
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
#now verify the server is really an IPA server
|
|
|
|
try:
|
2012-06-13 10:44:06 -05:00
|
|
|
ldap_url = "ldap://" + format_netloc(thost, 389)
|
|
|
|
root_logger.debug("Init LDAP connection with: %s", ldap_url)
|
|
|
|
lh = ldap.initialize(ldap_url)
|
2011-02-21 14:32:21 -06:00
|
|
|
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, True)
|
|
|
|
ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, "%s/ca.crt" % temp_ca_dir)
|
|
|
|
lh.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
|
|
|
|
lh.set_option(ldap.OPT_X_TLS_DEMAND, True)
|
|
|
|
lh.start_tls_s()
|
2007-08-16 17:00:16 -05:00
|
|
|
lh.simple_bind_s("","")
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2011-09-30 09:52:30 -05:00
|
|
|
# get IPA base DN
|
2011-11-15 13:39:31 -06:00
|
|
|
root_logger.debug("Search LDAP server for IPA base DN")
|
2011-09-30 09:52:30 -05:00
|
|
|
basedn = get_ipa_basedn(lh)
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2011-09-30 09:52:30 -05:00
|
|
|
if basedn is None:
|
2012-06-13 10:44:06 -05:00
|
|
|
root_logger.debug("The server is not an IPA server")
|
2011-09-28 15:31:38 -05:00
|
|
|
return [NOT_IPA_SERVER]
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2011-09-30 09:52:30 -05:00
|
|
|
self.basedn = basedn
|
2012-06-13 10:44:06 -05:00
|
|
|
self.basedn_source = 'From IPA server %s' % ldap_url
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
#search and return known realms
|
2012-06-13 10:44:06 -05:00
|
|
|
root_logger.debug(
|
|
|
|
"Search for (objectClass=krbRealmContainer) in %s (sub)",
|
|
|
|
self.basedn)
|
2007-08-30 18:40:54 -05:00
|
|
|
lret = lh.search_s("cn=kerberos,"+self.basedn, ldap.SCOPE_SUBTREE, "(objectClass=krbRealmContainer)")
|
2007-08-16 17:00:16 -05:00
|
|
|
if not lret:
|
|
|
|
#something very wrong
|
2011-09-28 15:31:38 -05:00
|
|
|
return [REALM_NOT_FOUND]
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
for lres in lret:
|
2012-06-13 10:44:06 -05:00
|
|
|
root_logger.debug("Found: %s", lres[0])
|
2007-08-16 17:00:16 -05:00
|
|
|
for lattr in lres[1]:
|
|
|
|
if lattr.lower() == "cn":
|
|
|
|
lrealms.append(lres[1][lattr][0])
|
2009-02-05 14:03:08 -06:00
|
|
|
|
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
if trealm:
|
|
|
|
for r in lrealms:
|
|
|
|
if trealm == r:
|
2011-09-28 15:31:38 -05:00
|
|
|
return [0, thost, trealm]
|
2007-08-16 17:00:16 -05:00
|
|
|
# must match or something is very wrong
|
2011-09-28 15:31:38 -05:00
|
|
|
return [REALM_NOT_FOUND]
|
2007-08-16 17:00:16 -05:00
|
|
|
else:
|
|
|
|
if len(lrealms) != 1:
|
|
|
|
#which one? we can't attach to a multi-realm server without DNS working
|
2011-09-28 15:31:38 -05:00
|
|
|
return [REALM_NOT_FOUND]
|
2007-08-16 17:00:16 -05:00
|
|
|
else:
|
2011-09-28 15:31:38 -05:00
|
|
|
return [0, thost, lrealms[0]]
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
#we shouldn't get here
|
2011-09-28 15:31:38 -05:00
|
|
|
return [UNKNOWN_ERROR]
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
except LDAPError, err:
|
2011-09-28 15:31:38 -05:00
|
|
|
if isinstance(err, ldap.TIMEOUT):
|
2011-11-15 13:39:31 -06:00
|
|
|
root_logger.error("LDAP Error: timeout")
|
2011-09-28 15:31:38 -05:00
|
|
|
return [NO_LDAP_SERVER]
|
|
|
|
|
|
|
|
if isinstance(err, ldap.INAPPROPRIATE_AUTH):
|
2011-11-15 13:39:31 -06:00
|
|
|
root_logger.debug("LDAP Error: Anonymous acces not allowed")
|
2011-09-28 15:31:38 -05:00
|
|
|
return [NO_ACCESS_TO_LDAP]
|
|
|
|
|
2011-11-15 13:39:31 -06:00
|
|
|
root_logger.error("LDAP Error: %s: %s" %
|
2011-09-28 15:31:38 -05:00
|
|
|
(err.args[0]['desc'], err.args[0].get('info', '')))
|
|
|
|
return [UNKNOWN_ERROR]
|
2007-08-16 17:00:16 -05:00
|
|
|
|
2011-02-21 14:32:21 -06:00
|
|
|
finally:
|
|
|
|
os.remove("%s/ca.crt" % temp_ca_dir)
|
2011-09-22 11:41:50 -05:00
|
|
|
os.rmdir(temp_ca_dir)
|
2011-02-21 14:32:21 -06:00
|
|
|
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2012-05-11 07:38:09 -05:00
|
|
|
def ipadns_search_srv(self, domain, srv_record_name, default_port,
|
|
|
|
break_on_first=True):
|
|
|
|
"""
|
|
|
|
Search for SRV records in given domain. When no record is found,
|
2012-06-13 10:44:06 -05:00
|
|
|
en empty list is returned
|
2012-05-11 07:38:09 -05:00
|
|
|
|
|
|
|
:param domain: Search domain name
|
|
|
|
:param srv_record_name: SRV record name, e.g. "_ldap._tcp"
|
|
|
|
:param default_port: When default_port is not None, it is being
|
|
|
|
checked with the port in SRV record and if they don't
|
|
|
|
match, the port from SRV record is appended to
|
|
|
|
found hostname in this format: "hostname:port"
|
|
|
|
:param break_on_first: break on the first find and return just one
|
|
|
|
entry
|
|
|
|
"""
|
|
|
|
servers = []
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2012-05-11 07:38:09 -05:00
|
|
|
qname = '%s.%s' % (srv_record_name, domain)
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2012-05-11 07:38:09 -05:00
|
|
|
root_logger.debug("Search DNS for SRV record of %s", qname)
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2012-05-11 07:38:09 -05:00
|
|
|
try:
|
|
|
|
answers = resolver.query(qname, rdatatype.SRV)
|
|
|
|
except DNSException, e:
|
|
|
|
root_logger.debug("DNS record not found: %s", e.__class__.__name__)
|
|
|
|
answers = []
|
|
|
|
|
|
|
|
for answer in answers:
|
|
|
|
root_logger.debug("DNS record found: %s", answer)
|
|
|
|
server = str(answer.target).rstrip(".")
|
|
|
|
if not server:
|
|
|
|
root_logger.debug("Cannot parse the hostname from SRV record: %s", answer)
|
|
|
|
continue
|
|
|
|
if default_port is not None and answer.port != default_port:
|
|
|
|
server = "%s:%s" % (server, str(answer.port))
|
|
|
|
servers.append(server)
|
|
|
|
if break_on_first:
|
2011-10-05 09:25:09 -05:00
|
|
|
break
|
|
|
|
|
|
|
|
return servers
|
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
def ipadnssearchkrb(self, tdomain):
|
2011-09-28 15:31:38 -05:00
|
|
|
realm = None
|
|
|
|
kdc = None
|
2007-08-16 17:00:16 -05:00
|
|
|
# now, check for a Kerberos realm the local host or domain is in
|
|
|
|
qname = "_kerberos." + tdomain
|
2012-05-11 07:38:09 -05:00
|
|
|
|
|
|
|
root_logger.debug("Search DNS for TXT record of %s", qname)
|
|
|
|
|
|
|
|
try:
|
|
|
|
answers = resolver.query(qname, rdatatype.TXT)
|
|
|
|
except DNSException, e:
|
|
|
|
root_logger.debug("DNS record not found: %s", e.__class__.__name__)
|
|
|
|
answers = []
|
|
|
|
|
|
|
|
for answer in answers:
|
|
|
|
root_logger.debug("DNS record found: %s", answer)
|
|
|
|
if answer.strings:
|
|
|
|
realm = answer.strings[0]
|
2007-08-16 17:00:16 -05:00
|
|
|
if realm:
|
|
|
|
break
|
2009-02-05 14:03:08 -06:00
|
|
|
|
2007-08-16 17:00:16 -05:00
|
|
|
if realm:
|
|
|
|
# now fetch server information for the realm
|
2012-05-11 07:38:09 -05:00
|
|
|
domain = realm.lower()
|
|
|
|
|
|
|
|
kdc = self.ipadns_search_srv(domain, '_kerberos._udp', 88,
|
|
|
|
break_on_first=False)
|
2007-08-16 17:00:16 -05:00
|
|
|
|
2011-03-21 08:50:05 -05:00
|
|
|
if not kdc:
|
2011-11-15 13:39:31 -06:00
|
|
|
root_logger.debug("SRV record for KDC not found! Realm: %s, SRV record: %s" % (realm, qname))
|
2012-05-11 07:38:09 -05:00
|
|
|
kdc = None
|
|
|
|
kdc = ','.join(kdc)
|
2011-07-06 09:30:24 -05:00
|
|
|
|
2012-06-13 10:44:06 -05:00
|
|
|
return realm, kdc
|