Ian Kent a3a09e
autofs-5.0.5 - refactor ldap sasl bind
Ian Kent a3a09e
Ian Kent a3a09e
From: Ian Kent <raven@themaw.net>
Ian Kent a3a09e
Ian Kent a3a09e
During the sasl authentication (and possible authentication method
Ian Kent a3a09e
selection) we establish a connection and then dispose of it and then
Ian Kent a3a09e
authenticate again. This is a little inefficient but some servers
Ian Kent a3a09e
don't like a second authentication using the same LDAP handle and
Ian Kent a3a09e
authentication fails when it should succeed. We should use the
Ian Kent a3a09e
authentication connection once we get it and not perform another
Ian Kent a3a09e
later.
Ian Kent a3a09e
Ian Kent a3a09e
Also fixed with this patch. If a server returns a set of
Ian Kent a3a09e
authentication mechanisms that all require authentication, then the
Ian Kent a3a09e
connection pointer is returned to the caller uninitialized (reported
Ian Kent a3a09e
and fix provided by Jeff Moyer).
Ian Kent a3a09e
---
Ian Kent a3a09e
Ian Kent a3a09e
 CHANGELOG             |    1 +
Ian Kent a3a09e
 modules/cyrus-sasl.c  |   55 ++++++++++++++++++---------------------------
Ian Kent a3a09e
 modules/lookup_ldap.c |   60 -------------------------------------------------
Ian Kent a3a09e
 3 files changed, 23 insertions(+), 93 deletions(-)
Ian Kent a3a09e
Ian Kent a3a09e
Ian Kent a3a09e
diff --git a/CHANGELOG b/CHANGELOG
Ian Kent a3a09e
index 674a48b..5adcca5 100644
Ian Kent a3a09e
--- a/CHANGELOG
Ian Kent a3a09e
+++ b/CHANGELOG
Ian Kent a3a09e
@@ -1,6 +1,7 @@
Ian Kent a3a09e
 ??/??/20?? autofs-5.0.6
Ian Kent a3a09e
 -----------------------
Ian Kent a3a09e
 - fix included map read fail handling.
Ian Kent a3a09e
+- refactor ldap sasl bind handling.
Ian Kent a3a09e
 
Ian Kent a3a09e
 03/09/2009 autofs-5.0.5
Ian Kent a3a09e
 -----------------------
Ian Kent a3a09e
diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
Ian Kent a3a09e
index 04001d0..828143e 100644
Ian Kent a3a09e
--- a/modules/cyrus-sasl.c
Ian Kent a3a09e
+++ b/modules/cyrus-sasl.c
Ian Kent a3a09e
@@ -87,8 +87,8 @@ static sasl_callback_t callbacks[] = {
Ian Kent a3a09e
 	{ SASL_CB_LIST_END, NULL, NULL },
Ian Kent a3a09e
 };
Ian Kent a3a09e
 
Ian Kent a3a09e
-static char *sasl_auth_id, *sasl_auth_secret;
Ian Kent a3a09e
-sasl_secret_t *sasl_secret;
Ian Kent a3a09e
+static char *sasl_auth_id = NULL;
Ian Kent a3a09e
+static char *sasl_auth_secret = NULL;
Ian Kent a3a09e
 
Ian Kent a3a09e
 static int
Ian Kent a3a09e
 sasl_log_func(void *context, int level, const char *message)
Ian Kent a3a09e
@@ -798,7 +798,7 @@ sasl_bind_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const c
Ian Kent a3a09e
 sasl_conn_t *
Ian Kent a3a09e
 sasl_choose_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
Ian Kent a3a09e
 {
Ian Kent a3a09e
-	sasl_conn_t *conn;
Ian Kent a3a09e
+	sasl_conn_t *conn = NULL;
Ian Kent a3a09e
 	int authenticated;
Ian Kent a3a09e
 	int i;
Ian Kent a3a09e
 	char **mechanisms;
Ian Kent a3a09e
@@ -845,22 +845,6 @@ sasl_choose_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
Ian Kent a3a09e
 	return conn;
Ian Kent a3a09e
 }
Ian Kent a3a09e
 
Ian Kent a3a09e
-int
Ian Kent a3a09e
-autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
Ian Kent a3a09e
-{
Ian Kent a3a09e
-	sasl_conn_t *conn;
Ian Kent a3a09e
-
Ian Kent a3a09e
-	if (!ctxt->sasl_mech)
Ian Kent a3a09e
-		return -1;
Ian Kent a3a09e
-
Ian Kent a3a09e
-	conn = sasl_bind_mech(logopt, ldap, ctxt, ctxt->sasl_mech);
Ian Kent a3a09e
-	if (!conn)
Ian Kent a3a09e
-		return -1;
Ian Kent a3a09e
-
Ian Kent a3a09e
-	ctxt->sasl_conn = conn;
Ian Kent a3a09e
-	return 0;
Ian Kent a3a09e
-}
Ian Kent a3a09e
-
Ian Kent a3a09e
 /*
Ian Kent a3a09e
  *  Routine called when unbinding an ldap connection.
Ian Kent a3a09e
  */
Ian Kent a3a09e
@@ -883,35 +867,40 @@ autofs_sasl_unbind(struct lookup_context *ctxt)
Ian Kent a3a09e
  * -1  -  Failure
Ian Kent a3a09e
  */
Ian Kent a3a09e
 int
Ian Kent a3a09e
-autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
Ian Kent a3a09e
+autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
Ian Kent a3a09e
 {
Ian Kent a3a09e
-	sasl_conn_t *conn;
Ian Kent a3a09e
+	sasl_conn_t *conn = NULL;
Ian Kent a3a09e
+
Ian Kent a3a09e
+	/* If we already have a connection use it */
Ian Kent a3a09e
+	if (ctxt->sasl_conn)
Ian Kent a3a09e
+		return 0;
Ian Kent a3a09e
 
Ian Kent a3a09e
 	sasl_auth_id = ctxt->user;
Ian Kent a3a09e
 	sasl_auth_secret = ctxt->secret;
Ian Kent a3a09e
 
Ian Kent a3a09e
+	if (ctxt->auth_required & LDAP_AUTH_AUTODETECT) {
Ian Kent a3a09e
+		if (ctxt->sasl_mech) {
Ian Kent a3a09e
+			free(ctxt->sasl_mech);
Ian Kent a3a09e
+			ctxt->sasl_mech = NULL;
Ian Kent a3a09e
+		}
Ian Kent a3a09e
+	}
Ian Kent a3a09e
+
Ian Kent a3a09e
 	/*
Ian Kent a3a09e
 	 *  If LDAP_AUTH_AUTODETECT is set, it means that there was no
Ian Kent a3a09e
 	 *  mechanism specified in the configuration file or auto
Ian Kent a3a09e
 	 *  selection has been requested, so try to auto-select an
Ian Kent a3a09e
 	 *  auth mechanism.
Ian Kent a3a09e
 	 */
Ian Kent a3a09e
-	if (!(ctxt->auth_required & LDAP_AUTH_AUTODETECT))
Ian Kent a3a09e
+	if (ctxt->sasl_mech)
Ian Kent a3a09e
 		conn = sasl_bind_mech(logopt, ldap, ctxt, ctxt->sasl_mech);
Ian Kent a3a09e
-	else {
Ian Kent a3a09e
-		if (ctxt->sasl_mech) {
Ian Kent a3a09e
-			free(ctxt->sasl_mech);
Ian Kent a3a09e
-			ctxt->sasl_mech = NULL;
Ian Kent a3a09e
-		}
Ian Kent a3a09e
+	else
Ian Kent a3a09e
 		conn = sasl_choose_mech(logopt, ldap, ctxt);
Ian Kent a3a09e
-	}
Ian Kent a3a09e
 
Ian Kent a3a09e
-	if (conn) {
Ian Kent a3a09e
-		sasl_dispose(&conn;;
Ian Kent a3a09e
-		return 0;
Ian Kent a3a09e
-	}
Ian Kent a3a09e
+	if (!conn)
Ian Kent a3a09e
+		return -1;
Ian Kent a3a09e
 
Ian Kent a3a09e
-	return -1;
Ian Kent a3a09e
+	ctxt->sasl_conn = conn;
Ian Kent a3a09e
+	return 0;
Ian Kent a3a09e
 }
Ian Kent a3a09e
 
Ian Kent a3a09e
 /*
Ian Kent a3a09e
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
Ian Kent a3a09e
index 2ecf5fe..f1fb9ce 100644
Ian Kent a3a09e
--- a/modules/lookup_ldap.c
Ian Kent a3a09e
+++ b/modules/lookup_ldap.c
Ian Kent a3a09e
@@ -59,7 +59,6 @@ struct ldap_search_params {
Ian Kent a3a09e
 	time_t age;
Ian Kent a3a09e
 };
Ian Kent a3a09e
 
Ian Kent a3a09e
-static LDAP *auth_init(unsigned logopt, const char *, struct lookup_context *);
Ian Kent a3a09e
 static int decode_percent_hack(const char *, char **);
Ian Kent a3a09e
 
Ian Kent a3a09e
 #ifndef HAVE_LDAP_CREATE_PAGE_CONTROL
Ian Kent a3a09e
@@ -600,33 +599,6 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c
Ian Kent a3a09e
 {
Ian Kent a3a09e
 	LDAP *ldap;
Ian Kent a3a09e
 
Ian Kent a3a09e
-#ifdef WITH_SASL
Ian Kent a3a09e
-	/*
Ian Kent a3a09e
-	 * Determine which authentication mechanism to use if we require
Ian Kent a3a09e
-	 * authentication.
Ian Kent a3a09e
-	 */
Ian Kent a3a09e
-	if (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT)) {
Ian Kent a3a09e
-		ldap = auth_init(logopt, uri, ctxt);
Ian Kent a3a09e
-		if (!ldap && ctxt->auth_required & LDAP_AUTH_AUTODETECT)
Ian Kent a3a09e
-			info(logopt,
Ian Kent a3a09e
-			     "no authentication mechanisms auto detected.");
Ian Kent a3a09e
-		if (!ldap) {
Ian Kent a3a09e
-			error(logopt, MODPREFIX
Ian Kent a3a09e
-			      "cannot initialize authentication setup");
Ian Kent a3a09e
-			return NULL;
Ian Kent a3a09e
-		}
Ian Kent a3a09e
-
Ian Kent a3a09e
-		if (!do_bind(logopt, ldap, uri, ctxt)) {
Ian Kent a3a09e
-			unbind_ldap_connection(logopt, ldap, ctxt);
Ian Kent a3a09e
-			autofs_sasl_dispose(ctxt);
Ian Kent a3a09e
-			error(logopt, MODPREFIX "cannot bind to server");
Ian Kent a3a09e
-			return NULL;
Ian Kent a3a09e
-		}
Ian Kent a3a09e
-
Ian Kent a3a09e
-		return ldap;
Ian Kent a3a09e
-	}
Ian Kent a3a09e
-#endif
Ian Kent a3a09e
-
Ian Kent a3a09e
 	ldap = do_connect(logopt, uri, ctxt);
Ian Kent a3a09e
 	if (!ldap) {
Ian Kent a3a09e
 		warn(logopt,
Ian Kent a3a09e
@@ -1074,38 +1046,6 @@ out:
Ian Kent a3a09e
 
Ian Kent a3a09e
 	return ret;
Ian Kent a3a09e
 }
Ian Kent a3a09e
-
Ian Kent a3a09e
-/*
Ian Kent a3a09e
- *  Reads in the xml configuration file and parses out the relevant
Ian Kent a3a09e
- *  information.  If there is no configuration file, then we fall back to
Ian Kent a3a09e
- *  trying all supported authentication mechanisms until one works.
Ian Kent a3a09e
- *
Ian Kent a3a09e
- *  Returns ldap connection on success, with authtype, user and secret
Ian Kent a3a09e
- *  filled in as appropriate.  Returns NULL on failre.
Ian Kent a3a09e
- */
Ian Kent a3a09e
-static LDAP *auth_init(unsigned logopt, const char *uri, struct lookup_context *ctxt)
Ian Kent a3a09e
-{
Ian Kent a3a09e
-	int ret;
Ian Kent a3a09e
-	LDAP *ldap;
Ian Kent a3a09e
-
Ian Kent a3a09e
-	ldap = init_ldap_connection(logopt, uri, ctxt);
Ian Kent a3a09e
-	if (!ldap)
Ian Kent a3a09e
-		return NULL;
Ian Kent a3a09e
-
Ian Kent a3a09e
-	/*
Ian Kent a3a09e
-	 *  Initialize the sasl library.  It is okay if user and secret
Ian Kent a3a09e
-	 *  are NULL, here.
Ian Kent a3a09e
-	 *
Ian Kent a3a09e
-	 *  The autofs_sasl_init routine will figure out which mechamism
Ian Kent a3a09e
-	 *  to use. If kerberos is used, it will also take care to initialize
Ian Kent a3a09e
-	 *  the credential cache and the client and service principals.
Ian Kent a3a09e
-	 */
Ian Kent a3a09e
-	ret = autofs_sasl_init(logopt, ldap, ctxt);
Ian Kent a3a09e
-	if (ret)
Ian Kent a3a09e
-		return NULL;
Ian Kent a3a09e
-
Ian Kent a3a09e
-	return ldap;
Ian Kent a3a09e
-}
Ian Kent a3a09e
 #endif
Ian Kent a3a09e
 
Ian Kent a3a09e
 /*