summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipa-client/ipaclient/ipadiscovery.py32
-rw-r--r--ipapython/ipautil.py37
2 files changed, 51 insertions, 18 deletions
diff --git a/ipa-client/ipaclient/ipadiscovery.py b/ipa-client/ipaclient/ipadiscovery.py
index c5567822e..f6c13fb67 100644
--- a/ipa-client/ipaclient/ipadiscovery.py
+++ b/ipa-client/ipaclient/ipadiscovery.py
@@ -24,7 +24,8 @@ import ipapython.dnsclient
import tempfile
import ldap
from ldap import LDAPError
-from ipapython.ipautil import run, CalledProcessError, valid_ip
+from ipapython.ipautil import run, CalledProcessError, valid_ip, get_ipa_basedn, \
+ realm_to_suffix
NOT_FQDN = -1
@@ -176,9 +177,15 @@ class IPADiscovery:
self.server = ldapret[1]
self.realm = ldapret[2]
- if ldapret[0] == NO_ACCESS_TO_LDAP and self.realm == None:
+ if ldapret[0] == NO_ACCESS_TO_LDAP and self.realm is None:
# Assume realm is the same as domain.upper()
self.realm = self.domain.upper()
+ logging.debug("Assuming realm is the same as domain: %s" % self.realm)
+
+ if ldapret[0] == NO_ACCESS_TO_LDAP and self.basedn is None:
+ # Generate suffix from realm
+ self.basedn = realm_to_suffix(self.realm)
+ logging.debug("Generate basedn from realm: %s" % self.basedn)
return ldapret[0]
@@ -229,25 +236,14 @@ class IPADiscovery:
lh.start_tls_s()
lh.simple_bind_s("","")
- logging.debug("Search rootdse")
- lret = lh.search_s("", ldap.SCOPE_BASE, "(objectClass=*)")
- for lattr in lret[0][1]:
- if lattr.lower() == "namingcontexts":
- self.basedn = lret[0][1][lattr][0]
+ # get IPA base DN
+ logging.debug("Search LDAP server for IPA base DN")
+ basedn = get_ipa_basedn(lh)
- logging.debug("Search for (info=*) in "+self.basedn+"(base)")
- lret = lh.search_s(self.basedn, ldap.SCOPE_BASE, "(info=IPA*)")
- if not lret:
+ if basedn is None:
return [NOT_IPA_SERVER]
- logging.debug("Found: "+str(lret))
- for lattr in lret[0][1]:
- if lattr.lower() == "info":
- linfo = lret[0][1][lattr][0].lower()
- break
-
- if not linfo or linfo.lower() != 'ipa v2.0':
- return [NOT_IPA_SERVER]
+ self.basedn = basedn
#search and return known realms
logging.debug("Search for (objectClass=krbRealmContainer) in "+self.basedn+"(sub)")
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 72cf400f9..cfc979edb 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -22,6 +22,8 @@ PLUGINS_SHARE_DIR = "/usr/share/ipa/plugins"
GEN_PWD_LEN = 12
+IPA_BASEDN_INFO = 'ipa v2.0'
+
import string
import tempfile
import logging
@@ -33,6 +35,7 @@ import stat
import shutil
import urllib2
import socket
+import ldap
from ipapython import ipavalidate
from types import *
@@ -1126,3 +1129,37 @@ def bind_port_responder(port, socket_stream=True, socket_timeout=None, responder
s.sendto(responder_data, addr)
finally:
s.close()
+
+def get_ipa_basedn(conn):
+ """
+ Get base DN of IPA suffix in given LDAP server.
+
+ None is returned if the suffix is not found
+
+ :param conn: Bound LDAP connection that will be used for searching
+ """
+ entries = conn.search_ext_s(
+ '', scope=ldap.SCOPE_BASE, attrlist=['namingcontexts']
+ )
+
+ contexts = entries[0][1]['namingcontexts']
+ for context in contexts:
+ logging.debug("Check if naming context '%s' is for IPA" % context)
+ try:
+ entry = conn.search_s(context, ldap.SCOPE_BASE, "(info=IPA*)")
+ except ldap.NO_SUCH_OBJECT:
+ logging.debug("LDAP server did not return info attribute to check for IPA version")
+ continue
+ if len(entry) == 0:
+ logging.debug("Info attribute with IPA server version not found")
+ continue
+ info = entry[0][1]['info'][0].lower()
+ if info != IPA_BASEDN_INFO:
+ logging.debug("Detected IPA server version (%s) did not match the client (%s)" \
+ % (info, IPA_BASEDN_INFO))
+ continue
+ logging.debug("Naming context '%s' is a valid IPA context" % context)
+ return context
+
+ return None
+