On Fri, 2011-09-30 at 09:24 +0200, Martin Kosek wrote:
> On Thu, 2011-09-29 at 16:45 -0400, Simo Sorce wrote:
> > On Thu, 2011-09-29 at 22:09 +0200, Martin Kosek wrote:
> > > On Thu, 2011-09-29 at 15:48 -0400, Simo Sorce wrote:
> > > > On Thu, 2011-09-29 at 15:20 +0200, Martin Kosek wrote:
> > > > > How to test:
> > > > > 1) Add new naming context (suffix) to your LDAP database with 
> > > > > installed
> > > > > IPA (see attached LDIF).
> > > > 
> > > > Btw I see no attached ldif ...
> > > > 
> > > 
> > > I know, I forgot to attach it to the first patch so I sent a second
> > > mail:
> > > 
> > > http://www.redhat.com/archives/freeipa-devel/2011-September/msg00434.html
> > > 
> > > Attaching the LDIF to this mail too.
> > 
> > Thanks,
> > tested and ACK
> > 
> > Seem both patches work together just fine even with multiple database
> > backends now.
> > 
> > Simo.
> > 
> 
> This worked fine only when LDAP allowed anonymous access. The
> installation crashed otherwise. Please check attached patch, it should
> work in both anonymous and non-anonymous scenario.
> 
> Martin
> 

Simo found that I changed default values of realm/kdc from his None back
to "". This is not necessary so I changed it back to None. The
functionality is still the same.

Martin
>From e96a71831585067b74ef475c6091c6b57be18e2b Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Fri, 30 Sep 2011 09:14:57 +0200
Subject: [PATCH] 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
---
 ipa-client/ipaclient/ipadiscovery.py |   32 +++++++++++++-----------------
 ipapython/ipautil.py                 |   36 ++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+), 18 deletions(-)

diff --git a/ipa-client/ipaclient/ipadiscovery.py b/ipa-client/ipaclient/ipadiscovery.py
index c5567822e0274660690b7c8d65620874d6341ce7..f6c13fb6712a6fa3c2d0d5fab157c10560866602 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 490981a4a903a68996e306548f9b16c64feed8ac..cfc979edbda20e2b0bfc20ae95174e75362b96c6 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
+
-- 
1.7.6.2

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

Reply via email to