This patch allows ipa-client-install to successfully complete if
anonymous access is not allowed on the LDAP server.

I have tested this by changing the value of
nsslapd-allow-anonymous-access from 'on' to 'rootdse' in cn=config
See NOTE about this option.

This patch warns the user that full verification of the LDAP server was
not possible and may even assume realm is domain.upper() if DNS
discovery is not possible.

With these caveats the installation on a DNS compliant domain works fine
against a IPA server with anonynous access to LDAP disabled with this
patch.

Fixes #1881

Simo.


NOTE: Setting rootdse nsslapd-allow-anonymous-access is standards
compliant as it still allows access anonymously to the rootdse entry.
Setting this option to 'off' prevents access even to rootdse and is not
a good idea (the client doesn't know what auth methods are avilable to
authenticate w/o access to rootdse)

-- 
Simo Sorce * Red Hat, Inc * New York
>From c091b8fc1258a95ae9cfa45547ddbaad74105f67 Mon Sep 17 00:00:00 2001
From: Simo Sorce <[email protected]>
Date: Wed, 28 Sep 2011 16:31:38 -0400
Subject: [PATCH] ipa-client-install: Fix joining when LDAP access is
 restricted

Fixes: https://fedorahosted.org/freeipa/ticket/1881
---
 ipa-client/ipa-install/ipa-client-install |    7 ++++
 ipa-client/ipaclient/ipadiscovery.py      |   52 ++++++++++++++++++----------
 2 files changed, 40 insertions(+), 19 deletions(-)

diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index 5ea055ff1967cc819baafd7bd3ae455b25b41e32..efa39cd6f58e4b41d65c0892c4cb6367892a206b 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -818,6 +818,13 @@ def install(options, env, fstore, statestore):
     if ret == ipadiscovery.NOT_IPA_SERVER:
         print >>sys.stderr, "%s is not an IPA v2 Server." % cli_server
         return CLIENT_INSTALL_ERROR
+
+    if ret == ipadiscovery.NO_ACCESS_TO_LDAP:
+        print "Warning: Anonymous access to the LDAP server is disabled."
+        print "Proceeding without strict verification."
+        print "Note: This is not an error if anonymous access has been explicitly restricted."
+        ret = 0
+
     if ret != 0:
         print >>sys.stderr, "Failed to verify that "+cli_server+" is an IPA Server."
         print >>sys.stderr, "This may mean that the remote server is not up or is not reachable"
diff --git a/ipa-client/ipaclient/ipadiscovery.py b/ipa-client/ipaclient/ipadiscovery.py
index 9d909fd1323ba29527ef6f8b9788135c42fd4322..44bdc4bff408f3e3cb75bb4bfb4a3d679637ab8d 100644
--- a/ipa-client/ipaclient/ipadiscovery.py
+++ b/ipa-client/ipaclient/ipadiscovery.py
@@ -31,7 +31,9 @@ NOT_FQDN = -1
 NO_LDAP_SERVER = -2
 REALM_NOT_FOUND = -3
 NOT_IPA_SERVER = -4
+NO_ACCESS_TO_LDAP = -5
 BAD_HOST_CONFIG = -10
+UNKNOWN_ERROR = -15
 
 class IPADiscovery:
 
@@ -170,13 +172,15 @@ class IPADiscovery:
         # check ldap now
         ldapret = self.ipacheckldap(self.server, self.realm)
 
-        if not ldapret:
-            return NOT_IPA_SERVER
+        if ldapret[0] == 0:
+            self.server = ldapret[0]
+            self.realm = ldapret[1]
 
-        self.server = ldapret[0]
-        self.realm = ldapret[1]
+        if ldapret[0] == NO_ACCESS_TO_LDAP and self.realm == None:
+            # Assume realm is the same as domain.upper()
+            self.realm = self.domain.upper()
 
-        return 0
+        return ldapret[0]
 
     def ipacheckldap(self, thost, trealm):
         """
@@ -185,7 +189,12 @@ class IPADiscovery:
         so the remote IPA CA cert must be available at
         http://HOST/ipa/config/ca.crt
 
-        Returns a list [host, realm] or an empty list on error.
+        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
+                anonymous binds are siabled)
+            2 means the server is certainly not an IPA server
         """
 
         lret = []
@@ -207,7 +216,7 @@ class IPADiscovery:
             run(["/usr/bin/wget", "-O", "%s/ca.crt" % temp_ca_dir, "http://%s/ipa/config/ca.crt"; % thost])
         except CalledProcessError, e:
             logging.debug('Retrieving CA from %s failed.\n%s' % (thost, str(e)))
-            return []
+            return [NOT_IPA_SERVER]
 
         #now verify the server is really an IPA server
         try:
@@ -229,7 +238,7 @@ class IPADiscovery:
             logging.debug("Search for (info=*) in "+self.basedn+"(base)")
             lret = lh.search_s(self.basedn, ldap.SCOPE_BASE, "(info=IPA*)")
             if not lret:
-                return []
+                return [NOT_IPA_SERVER]
             logging.debug("Found: "+str(lret))
 
             for lattr in lret[0][1]:
@@ -238,14 +247,14 @@ class IPADiscovery:
                     break
 
             if not linfo or linfo.lower() != 'ipa v2.0':
-                return []
+                return [NOT_IPA_SERVER]
 
             #search and return known realms
             logging.debug("Search for (objectClass=krbRealmContainer) in "+self.basedn+"(sub)")
             lret = lh.search_s("cn=kerberos,"+self.basedn, ldap.SCOPE_SUBTREE, "(objectClass=krbRealmContainer)")
             if not lret:
                 #something very wrong
-                return []
+                return [REALM_NOT_FOUND]
             logging.debug("Found: "+str(lret))
 
             for lres in lret:
@@ -259,24 +268,29 @@ class IPADiscovery:
                     if trealm == r:
                         return [thost, trealm]
                 # must match or something is very wrong
-                return []
+                return [REALM_NOT_FOUND]
             else:
                 if len(lrealms) != 1:
                     #which one? we can't attach to a multi-realm server without DNS working
-                    return []
+                    return [REALM_NOT_FOUND]
                 else:
-                    return [thost, lrealms[0]]
+                    return [0, thost, lrealms[0]]
 
             #we shouldn't get here
-            return []
+            return [UNKNOWN_ERROR]
 
         except LDAPError, err:
-            if not isinstance(err, ldap.TIMEOUT):
-                logging.error("LDAP Error: %s: %s" %
-                   (err.args[0]['desc'], err.args[0].get('info', '')))
-            else:
+            if isinstance(err, ldap.TIMEOUT):
                 logging.error("LDAP Error: timeout")
-            return []
+                return [NO_LDAP_SERVER]
+
+            if isinstance(err, ldap.INAPPROPRIATE_AUTH):
+                logging.debug("LDAP Error: Anonymous acces not allowed")
+                return [NO_ACCESS_TO_LDAP]
+
+            logging.error("LDAP Error: %s: %s" %
+               (err.args[0]['desc'], err.args[0].get('info', '')))
+            return [UNKNOWN_ERROR]
 
         finally:
             os.remove("%s/ca.crt" % temp_ca_dir)
-- 
1.7.6.2

_______________________________________________
Freeipa-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to