summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Kosek <mkosek@redhat.com>2011-09-30 09:14:57 +0200
committerMartin Kosek <mkosek@redhat.com>2011-09-30 16:54:30 +0200
commit848d37c092979b3fde08f8d228b039672525c0b2 (patch)
treee05b11bf1061810d62fd9663871b90b284e8d9e3
parent8fb70fd24938f9106821f323ae8557a9bc814846 (diff)
downloadfreeipa-848d37c092979b3fde08f8d228b039672525c0b2.tar.gz
freeipa-848d37c092979b3fde08f8d228b039672525c0b2.tar.xz
freeipa-848d37c092979b3fde08f8d228b039672525c0b2.zip
ipa-client assumes a single namingcontext
When LDAP server contains more that one suffixes, the ipa client installation does not detect it as IPA server and fails to install. Fix ipa server discovery so that it correctly searches all naming contexts for the IPA one. https://fedorahosted.org/freeipa/ticket/1868
-rw-r--r--ipa-client/ipaclient/ipadiscovery.py32
-rw-r--r--ipapython/ipautil.py36
2 files changed, 50 insertions, 18 deletions
diff --git a/ipa-client/ipaclient/ipadiscovery.py b/ipa-client/ipaclient/ipadiscovery.py
index c5567822..f6c13fb6 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 490981a4..cfc979ed 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 *
@@ -1127,3 +1130,36 @@ def bind_port_responder(port, socket_stream=True, socket_timeout=None, responder
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
+