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
