Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 130701790bf2d95e902edf16031ff596 > files > 220

autofs-5.0.1-0.rc2.164.el5_8.src.rpm

diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
index 18733f3..303b7f2 100644
--- a/modules/cyrus-sasl.c
+++ b/modules/cyrus-sasl.c
@@ -75,6 +75,7 @@ static const char *krb5ccval = "MEMORY:_autofstkt";
 static pthread_mutex_t krb5cc_mutex = PTHREAD_MUTEX_INITIALIZER;
 static unsigned int krb5cc_in_use = 0;
 
+static unsigned int init_callbacks = 1;
 static int sasl_log_func(void *, int, const char *);
 static int getpass_func(sasl_conn_t *, void *, int, sasl_secret_t **);
 static int getuser_func(void *, int, const char **, unsigned *);
@@ -386,7 +387,7 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
 
 	debug(logopt,
 	      "initializing kerberos ticket: client principal %s ",
-	      ctxt->client_princ ? "" : "autofsclient");
+	      ctxt->client_princ ? ctxt->client_princ : "autofsclient");
 
 	ret = krb5_init_context(&ctxt->krb5ctxt);
 	if (ret) {
@@ -599,8 +600,8 @@ sasl_bind_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const c
 
 	/* OK and CONTINUE are the only non-fatal return codes here. */
 	if ((result != SASL_OK) && (result != SASL_CONTINUE)) {
-		error(logopt, "sasl_client start failed with error: %s",
-		      sasl_errdetail(conn));
+		warn(logopt, "sasl_client_start failed for %s", host);
+		debug(logopt, "sasl_client_start: %s", sasl_errdetail(conn));
 		ldap_memfree(host);
 		sasl_dispose(&conn);
 		return NULL;
@@ -721,23 +722,30 @@ autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
 	sasl_conn_t *conn;
 
 	/* Start up Cyrus SASL--only needs to be done once. */
-	if (sasl_client_init(callbacks) != SASL_OK) {
+	if (init_callbacks && sasl_client_init(callbacks) != SASL_OK) {
 		error(logopt, "sasl_client_init failed");
 		return -1;
 	}
+	init_callbacks = 0;
 
 	sasl_auth_id = ctxt->user;
 	sasl_auth_secret = ctxt->secret;
 
 	/*
-	 *  If sasl_mech was not filled in, it means that there was no
-	 *  mechanism specified in the configuration file.  Try to auto-
-	 *  select one.
+	 *  If LDAP_AUTH_AUTODETECT is set, it means that there was no
+	 *  mechanism specified in the configuration file or auto
+	 *  selection has been requested, so try to auto-select an
+	 *  auth mechanism.
 	 */
-	if (ctxt->sasl_mech)
+	if (!(ctxt->auth_required & LDAP_AUTH_AUTODETECT))
 		conn = sasl_bind_mech(logopt, ldap, ctxt, ctxt->sasl_mech);
-	else
+	else {
+		if (ctxt->sasl_mech) {
+			free(ctxt->sasl_mech);
+			ctxt->sasl_mech = NULL;
+		}
 		conn = sasl_choose_mech(logopt, ldap, ctxt);
+	}
 
 	if (conn) {
 		sasl_dispose(&conn);
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 7effbf1..93f0477 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -402,8 +402,7 @@ static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
 	debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s",
 	      ctxt->auth_required, ctxt->sasl_mech);
 
-	if (ctxt->sasl_mech ||
-	   (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT))) {
+	if (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT)) {
 		rv = autofs_sasl_bind(logopt, ldap, ctxt);
 		debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
 	} else {
@@ -497,7 +496,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c
 	 * Determine which authentication mechanism to use if we require
 	 * authentication.
 	 */
-	if (ctxt->auth_required & LDAP_AUTH_REQUIRED) {
+	if (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT)) {
 		ldap = auth_init(logopt, uri, ctxt);
 		if (!ldap && ctxt->auth_required & LDAP_AUTH_AUTODETECT)
 			info(logopt,
@@ -510,6 +509,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c
 
 		if (!do_bind(logopt, ldap, ctxt)) {
 			unbind_ldap_connection(logopt, ldap, ctxt);
+			autofs_sasl_done(ctxt);
 			error(logopt, MODPREFIX "cannot bind to server");
 			return NULL;
 		}
@@ -541,6 +541,7 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
 	while(p != ctxt->uri) {
 		this = list_entry(p, struct ldap_uri, list);
 		p = p->next;
+		debug(logopt, "trying server %s", this->uri);
 		ldap = connect_to_server(logopt, this->uri, ctxt);
 		if (ldap) {
 			info(logopt, "connected to uri %s", this->uri);
@@ -563,22 +564,23 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
 
 static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
 {
+	struct ldap_uri *this;
 	LDAP *ldap;
 
 	if (ctxt->server || !ctxt->uri) {
 		ldap = do_connect(logopt, ctxt->server, ctxt);
 		return ldap;
-	} else {
-		struct ldap_uri *this;
-		this = list_entry(ctxt->uri->next, struct ldap_uri, list);
-		ldap = do_connect(logopt, this->uri, ctxt);
-		if (ldap)
-			return ldap;
-		/* Failed to connect, put at end of list */
-		list_del_init(&this->list);
-		list_add_tail(&this->list, ctxt->uri);
 	}
 
+	this = list_entry(ctxt->uri->next, struct ldap_uri, list);
+	ldap = do_connect(logopt, this->uri, ctxt);
+	if (ldap)
+		return ldap;
+
+	/* Failed to connect, put at end of list */
+	list_del_init(&this->list);
+	list_add_tail(&this->list, ctxt->uri);
+
 #ifdef WITH_SASL
 	autofs_sasl_done(ctxt);
 #endif
@@ -844,6 +846,8 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
 	ctxt->tls_required = tls_required;
 	ctxt->auth_required = auth_required;
 	ctxt->sasl_mech = authtype;
+	if (!authtype && (auth_required & LDAP_AUTH_REQUIRED))
+		ctxt->auth_required |= LDAP_AUTH_AUTODETECT;
 	ctxt->user = user;
 	ctxt->secret = secret;
 	ctxt->client_princ = client_princ;
@@ -886,16 +890,6 @@ static LDAP *auth_init(unsigned logopt, const char *uri, struct lookup_context *
 	int ret;
 	LDAP *ldap;
 
-	/*
-	 *  First, check to see if a preferred authentication method was
-	 *  specified by the user.  parse_ldap_config will return error
-	 *  if the permissions on the file were incorrect, or if the
-	 *  specified authentication type is not valid.
-	 */
-	ret = parse_ldap_config(logopt, ctxt);
-	if (ret)
-		return NULL;
-
 	ldap = init_ldap_connection(logopt, uri, ctxt);
 	if (!ldap)
 		return NULL;
@@ -909,10 +903,8 @@ static LDAP *auth_init(unsigned logopt, const char *uri, struct lookup_context *
 	 *  the credential cache and the client and service principals.
 	 */
 	ret = autofs_sasl_init(logopt, ldap, ctxt);
-	if (ret) {
-		ctxt->sasl_mech = NULL;
+	if (ret)
 		return NULL;
-	}
 
 	return ldap;
 }
@@ -1134,6 +1126,8 @@ static void free_context(struct lookup_context *ctxt)
 		free(ctxt->user);
 	if (ctxt->secret)
 		free(ctxt->secret);
+	if (ctxt->client_princ)
+		free(ctxt->client_princ);
 	if (ctxt->mapname)
 		free(ctxt->mapname);
 	if (ctxt->qdn)
@@ -1184,6 +1178,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
 	struct lookup_context *ctxt;
 	char buf[MAX_ERR_BUF];
 	LDAP *ldap = NULL;
+	int ret;
 
 	*context = NULL;
 
@@ -1224,6 +1219,20 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
 		}
 	}
 
+#ifdef WITH_SASL
+	/*
+	 *  First, check to see if a preferred authentication method was
+	 *  specified by the user.  parse_ldap_config will return error
+	 *  if the permissions on the file were incorrect, or if the
+	 *  specified authentication type is not valid.
+	 */
+	ret = parse_ldap_config(LOGOPT_NONE, ctxt);
+	if (ret) {
+		free_context(ctxt);
+		return 1;
+	}
+#endif
+
 	if (ctxt->server || !ctxt->uri) {
 		ldap = connect_to_server(LOGOPT_NONE, ctxt->server, ctxt);
 		if (!ldap) {