autofs-5.1.1 - fix sasl connection concurrancy problem
From: Ian Kent <raven@themaw.net>
After using the contributed Cyrus SASL code in autofs for years I've
finally looked at the Cyrus SASL C API RFC only to find that the
library isn't thread safe unless a connection context per thread is
used, similar to the LDAP library.
To be fair this code originated prior to the threaded version of
autofs so it's my bad I didn't check.
But having seen this I have no choice but to make the sasl context
per thread not per autofs lookup context.
Also extend the mutual exclusion even further.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/lookup_ldap.h | 16 ++--
modules/cyrus-sasl.c | 46 ++++++-----
modules/lookup_ldap.c | 198 +++++++++++++++++++++++++-------------------------
4 files changed, 136 insertions(+), 125 deletions(-)
--- autofs-5.0.7.orig/CHANGELOG
+++ autofs-5.0.7/CHANGELOG
@@ -197,6 +197,7 @@
- fix update_hosts_mounts() return.
- change lookup to use reinit instead of reopen.
- fix unbind sasl external mech.
+- fix sasl connection concurrancy problem.
25/07/2012 autofs-5.0.7
=======================
--- autofs-5.0.7.orig/include/lookup_ldap.h
+++ autofs-5.0.7/include/lookup_ldap.h
@@ -34,6 +34,13 @@ struct ldap_searchdn {
struct ldap_searchdn *next;
};
+struct ldap_conn {
+ LDAP *ldap;
+#ifdef WITH_SASL
+ sasl_conn_t *sasl_conn;
+#endif
+};
+
struct lookup_context {
char *mapname;
unsigned int format;
@@ -86,7 +93,6 @@ struct lookup_context {
/* Kerberos */
krb5_context krb5ctxt;
krb5_ccache krb5_ccache;
- sasl_conn_t *sasl_conn;
/* SASL external */
char *extern_cert;
char *extern_key;
@@ -113,16 +119,16 @@ struct lookup_context {
/* lookup_ldap.c */
LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt);
-int unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
+int unbind_ldap_connection(unsigned logopt, struct ldap_conn *conn, struct lookup_context *ctxt);
int authtype_requires_creds(const char *authtype);
#ifdef WITH_SASL
/* cyrus-sasl.c */
int autofs_sasl_client_init(unsigned logopt);
int autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
-int autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
-void autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt);
-void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt);
+int autofs_sasl_bind(unsigned logopt, struct ldap_conn *conn, struct lookup_context *ctxt);
+void autofs_sasl_unbind(struct ldap_conn *conn, struct lookup_context *ctxt);
+void autofs_sasl_dispose(struct ldap_conn *conn, struct lookup_context *ctxt);
void autofs_sasl_done(void);
/* cyrus-sasl-extern */
int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt);
--- autofs-5.0.7.orig/modules/cyrus-sasl.c
+++ autofs-5.0.7/modules/cyrus-sasl.c
@@ -855,16 +855,19 @@ sasl_choose_mech(unsigned logopt, LDAP *
* Routine called when unbinding an ldap connection.
*/
void
-autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt)
+autofs_sasl_unbind(struct ldap_conn *conn, struct lookup_context *ctxt)
{
if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) {
- ldap_unbind_s(ldap);
+ if (conn->ldap) {
+ ldap_unbind_s(conn->ldap);
+ conn->ldap = NULL;
+ }
return;
}
- if (ctxt->sasl_conn) {
- sasl_dispose(&ctxt->sasl_conn);
- ctxt->sasl_conn = NULL;
+ if (conn->sasl_conn) {
+ sasl_dispose(&conn->sasl_conn);
+ conn->sasl_conn = NULL;
}
}
@@ -878,13 +881,10 @@ autofs_sasl_unbind(LDAP *ldap, struct lo
* -1 - Failure
*/
int
-autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
+autofs_sasl_bind(unsigned logopt,
+ struct ldap_conn *conn, struct lookup_context *ctxt)
{
- sasl_conn_t *conn = NULL;
-
- /* If we already have a connection use it */
- if (ctxt->sasl_conn)
- return 0;
+ sasl_conn_t *sasl_conn = NULL;
if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) {
int result;
@@ -893,7 +893,7 @@ autofs_sasl_bind(unsigned logopt, LDAP *
"Attempting sasl bind with mechanism %s",
ctxt->sasl_mech);
- result = do_sasl_extern(ldap, ctxt);
+ result = do_sasl_extern(conn->ldap, ctxt);
if (result)
debug(logopt,
"Failed to authenticate with mech %s",
@@ -923,14 +923,16 @@ autofs_sasl_bind(unsigned logopt, LDAP *
* auth mechanism.
*/
if (ctxt->sasl_mech)
- conn = sasl_bind_mech(logopt, ldap, ctxt, ctxt->sasl_mech);
+ sasl_conn = sasl_bind_mech(logopt,
+ conn->ldap, ctxt, ctxt->sasl_mech);
else
- conn = sasl_choose_mech(logopt, ldap, ctxt);
+ sasl_conn = sasl_choose_mech(logopt, conn->ldap, ctxt);
if (!conn)
return -1;
- ctxt->sasl_conn = conn;
+ conn->sasl_conn = sasl_conn;
+
return 0;
}
@@ -938,19 +940,21 @@ autofs_sasl_bind(unsigned logopt, LDAP *
* Destructor routine. This should be called when finished with an ldap
* session.
*/
-void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt)
+void autofs_sasl_dispose(struct ldap_conn *conn, struct lookup_context *ctxt)
{
int status, ret;
if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) {
- if (ldap)
- ldap_unbind_s(ldap);
+ if (conn && conn->ldap) {
+ ldap_unbind_s(conn->ldap);
+ conn->ldap = NULL;
+ }
return;
}
- if (ctxt->sasl_conn) {
- sasl_dispose(&ctxt->sasl_conn);
- ctxt->sasl_conn = NULL;
+ if (conn && conn->sasl_conn) {
+ sasl_dispose(&conn->sasl_conn);
+ conn->sasl_conn = NULL;
}
if (ctxt->kinit_successful) {
--- autofs-5.0.7.orig/modules/lookup_ldap.c
+++ autofs-5.0.7/modules/lookup_ldap.c
@@ -214,7 +214,9 @@ int bind_ldap_simple(unsigned logopt, LD
return 0;
}
-int __unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
+int __unbind_ldap_connection(unsigned logopt,
+ struct ldap_conn *conn,
+ struct lookup_context *ctxt)
{
int rv = LDAP_SUCCESS;
@@ -222,30 +224,35 @@ int __unbind_ldap_connection(unsigned lo
ctxt->use_tls = LDAP_TLS_INIT;
#ifdef WITH_SASL
if (ctxt->auth_required & LDAP_NEED_AUTH)
- autofs_sasl_unbind(ldap, ctxt);
- else
- rv = ldap_unbind_ext(ldap, NULL, NULL);
-#else
- rv = ldap_unbind_ext(ldap, NULL, NULL);
+ autofs_sasl_unbind(conn, ctxt);
+ /* No, sasl_dispose does not release the ldap connection
+ * unless it's using sasl EXTERNAL
+ */
#endif
+ if (conn->ldap) {
+ rv = ldap_unbind_ext(conn->ldap, NULL, NULL);
+ conn->ldap = NULL;
+ }
if (rv != LDAP_SUCCESS)
error(logopt, "unbind failed: %s", ldap_err2string(rv));
return rv;
}
-int unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
+int unbind_ldap_connection(unsigned logopt,
+ struct ldap_conn *conn,
+ struct lookup_context *ctxt)
{
int rv;
ldapinit_mutex_lock();
- rv = __unbind_ldap_connection(logopt, ldap, ctxt);
+ rv = __unbind_ldap_connection(logopt, conn, ctxt);
ldapinit_mutex_unlock();
return rv;
}
-LDAP *__init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt)
+LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt)
{
LDAP *ldap = NULL;
struct timeval timeout = { ctxt->timeout, 0 };
@@ -313,7 +320,7 @@ LDAP *__init_ldap_connection(unsigned lo
return NULL;
}
ctxt->use_tls = LDAP_TLS_DONT_USE;
- ldap = __init_ldap_connection(logopt, uri, ctxt);
+ ldap = init_ldap_connection(logopt, uri, ctxt);
if (ldap)
ctxt->use_tls = LDAP_TLS_INIT;
return ldap;
@@ -324,17 +331,6 @@ LDAP *__init_ldap_connection(unsigned lo
return ldap;
}
-LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt)
-{
- LDAP *ldap;
-
- ldapinit_mutex_lock();
- ldap = __init_ldap_connection(logopt, uri, ctxt);
- ldapinit_mutex_unlock();
-
- return ldap;
-}
-
static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key)
{
char buf[MAX_ERR_BUF];
@@ -574,33 +570,32 @@ static int find_query_dn(unsigned logopt
return 0;
}
-static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt)
+static int do_bind(unsigned logopt, struct ldap_conn *conn,
+ const char *uri, struct lookup_context *ctxt)
{
char *host = NULL, *nhost;
int rv;
- ldapinit_mutex_lock();
#ifdef WITH_SASL
debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s",
ctxt->auth_required, ctxt->sasl_mech);
if (ctxt->auth_required & LDAP_NEED_AUTH) {
- rv = autofs_sasl_bind(logopt, ldap, ctxt);
+ rv = autofs_sasl_bind(logopt, conn, ctxt);
debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
} else {
- rv = bind_ldap_simple(logopt, ldap, uri, ctxt);
+ rv = bind_ldap_simple(logopt, conn->ldap, uri, ctxt);
debug(logopt, MODPREFIX "ldap simple bind returned %d", rv);
}
#else
- rv = bind_ldap_simple(logopt, ldap, uri, ctxt);
+ rv = bind_ldap_simple(logopt, conn->ldap, uri, ctxt);
debug(logopt, MODPREFIX "ldap simple bind returned %d", rv);
#endif
- ldapinit_mutex_unlock();
if (rv != 0)
return 0;
- rv = ldap_get_option(ldap, LDAP_OPT_HOST_NAME, &host);
+ rv = ldap_get_option(conn->ldap, LDAP_OPT_HOST_NAME, &host);
if (rv != LDAP_SUCCESS || !host) {
debug(logopt, "failed to get hostname for connection");
return 0;
@@ -634,15 +629,12 @@ static int do_bind(unsigned logopt, LDAP
return 1;
}
-static int do_connect(unsigned logopt, LDAP **ldap,
+static int do_connect(unsigned logopt, struct ldap_conn *conn,
const char *uri, struct lookup_context *ctxt)
{
char *cur_host = NULL;
- LDAP *handle;
int ret = NSS_STATUS_SUCCESS;
- *ldap = NULL;
-
#ifdef WITH_SASL
if (ctxt->extern_cert && ctxt->extern_key) {
set_env(logopt, ENV_LDAPTLS_CERT, ctxt->extern_cert);
@@ -650,8 +642,8 @@ static int do_connect(unsigned logopt, L
}
#endif
- handle = init_ldap_connection(logopt, uri, ctxt);
- if (!handle) {
+ conn->ldap = init_ldap_connection(logopt, uri, ctxt);
+ if (!conn->ldap) {
ret = NSS_STATUS_UNAVAIL;
goto out;
}
@@ -661,8 +653,8 @@ static int do_connect(unsigned logopt, L
cur_host = ctxt->cur_host;
uris_mutex_unlock(ctxt);
- if (!do_bind(logopt, handle, uri, ctxt)) {
- unbind_ldap_connection(logopt, handle, ctxt);
+ if (!do_bind(logopt, conn, uri, ctxt)) {
+ __unbind_ldap_connection(logopt, conn, ctxt);
ret = NSS_STATUS_UNAVAIL;
goto out;
}
@@ -673,7 +665,6 @@ static int do_connect(unsigned logopt, L
uris_mutex_lock(ctxt);
if (ctxt->schema && ctxt->qdn && (cur_host == ctxt->cur_host)) {
uris_mutex_unlock(ctxt);
- *ldap = handle;
goto out;
}
uris_mutex_unlock(ctxt);
@@ -684,8 +675,8 @@ static int do_connect(unsigned logopt, L
* base dn for searches.
*/
if (!ctxt->schema) {
- if (!find_query_dn(logopt, handle, ctxt)) {
- unbind_ldap_connection(logopt, handle, ctxt);
+ if (!find_query_dn(logopt, conn->ldap, ctxt)) {
+ __unbind_ldap_connection(logopt, conn, ctxt);
ret = NSS_STATUS_NOTFOUND;
warn(logopt,
MODPREFIX "failed to find valid query dn");
@@ -694,21 +685,21 @@ static int do_connect(unsigned logopt, L
} else if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) {
const char *class = ctxt->schema->map_class;
const char *key = ctxt->schema->map_attr;
- if (!get_query_dn(logopt, handle, ctxt, class, key)) {
- unbind_ldap_connection(logopt, handle, ctxt);
+ if (!get_query_dn(logopt, conn->ldap, ctxt, class, key)) {
+ __unbind_ldap_connection(logopt, conn, ctxt);
ret = NSS_STATUS_NOTFOUND;
error(logopt, MODPREFIX "failed to get query dn");
goto out;
}
}
- *ldap = handle;
out:
return ret;
}
static unsigned long get_amd_timestamp(struct lookup_context *ctxt)
{
+ struct ldap_conn conn;
LDAP *ldap;
LDAPMessage *result = NULL, *e;
char *query;
@@ -719,9 +710,11 @@ static unsigned long get_amd_timestamp(s
unsigned long timestamp = 0;
int rv, l, ql;
- rv = do_connect(LOGOPT_ANY, &ldap, ctxt->server, ctxt);
+ memset(&conn, 0, sizeof(struct ldap_conn));
+ rv = do_connect(LOGOPT_ANY, &conn, ctxt->server, ctxt);
if (rv != NSS_STATUS_SUCCESS)
return 0;
+ ldap = conn.ldap;
map = amd_timestamp.map_attr;
class = amd_timestamp.entry_class;
@@ -758,7 +751,7 @@ static unsigned long get_amd_timestamp(s
rv = ldap_search_s(ldap, ctxt->base, scope, query, attrs, 0, &result);
if ((rv != LDAP_SUCCESS) || !result) {
crit(LOGOPT_ANY, MODPREFIX "timestamp query failed %s", query);
- unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt);
+ unbind_ldap_connection(LOGOPT_ANY, &conn, ctxt);
if (result)
ldap_msgfree(result);
free(query);
@@ -770,7 +763,7 @@ static unsigned long get_amd_timestamp(s
debug(LOGOPT_ANY,
MODPREFIX "got answer, but no entry for timestamp");
ldap_msgfree(result);
- unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt);
+ unbind_ldap_connection(LOGOPT_ANY, &conn, ctxt);
free(query);
return CHE_MISSING;
}
@@ -821,18 +814,18 @@ next:
}
ldap_msgfree(result);
- unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt);
+ unbind_ldap_connection(LOGOPT_ANY, &conn, ctxt);
free(query);
return timestamp;
}
-static int connect_to_server(unsigned logopt, LDAP **ldap,
+static int connect_to_server(unsigned logopt, struct ldap_conn *conn,
const char *uri, struct lookup_context *ctxt)
{
int ret;
- ret = do_connect(logopt, ldap, uri, ctxt);
+ ret = do_connect(logopt, conn, uri, ctxt);
if (ret != NSS_STATUS_SUCCESS) {
warn(logopt,
MODPREFIX "couldn't connect to server %s",
@@ -842,7 +835,7 @@ static int connect_to_server(unsigned lo
return ret;
}
-static int find_dc_server(unsigned logopt, LDAP **ldap,
+static int find_dc_server(unsigned logopt, struct ldap_conn *conn,
const char *uri, struct lookup_context *ctxt)
{
char *str, *tok, *ptr = NULL;
@@ -858,7 +851,7 @@ static int find_dc_server(unsigned logop
int rv;
debug(logopt, "trying server uri %s", this);
- rv = connect_to_server(logopt, ldap, this, ctxt);
+ rv = connect_to_server(logopt, conn, this, ctxt);
if (rv == NSS_STATUS_SUCCESS) {
info(logopt, "connected to uri %s", this);
free(str);
@@ -875,7 +868,7 @@ static int find_dc_server(unsigned logop
}
static int find_server(unsigned logopt,
- LDAP **ldap, struct lookup_context *ctxt)
+ struct ldap_conn *conn, struct lookup_context *ctxt)
{
struct ldap_uri *this = NULL;
struct list_head *p, *first;
@@ -906,7 +899,7 @@ static int find_server(unsigned logopt,
if (!strstr(this->uri, ":///")) {
uri = strdup(this->uri);
debug(logopt, "trying server uri %s", uri);
- rv = connect_to_server(logopt, ldap, uri, ctxt);
+ rv = connect_to_server(logopt, conn, uri, ctxt);
if (rv == NSS_STATUS_SUCCESS) {
ret = NSS_STATUS_SUCCESS;
info(logopt, "connected to uri %s", uri);
@@ -928,7 +921,7 @@ static int find_server(unsigned logopt,
dclist = tmp;
uri = strdup(dclist->uri);
}
- rv = find_dc_server(logopt, ldap, uri, ctxt);
+ rv = find_dc_server(logopt, conn, uri, ctxt);
if (rv == NSS_STATUS_SUCCESS) {
ret = NSS_STATUS_SUCCESS;
free(uri);
@@ -947,7 +940,7 @@ static int find_server(unsigned logopt,
}
uris_mutex_lock(ctxt);
- if (ldap)
+ if (conn->ldap)
ctxt->uri = this;
if (dclist) {
if (!ctxt->dclist)
@@ -965,37 +958,39 @@ static int find_server(unsigned logopt,
}
static int do_reconnect(unsigned logopt,
- LDAP **ldap, struct lookup_context *ctxt)
+ struct ldap_conn *conn, struct lookup_context *ctxt)
{
int ret = NSS_STATUS_UNAVAIL;
int dcrv = NSS_STATUS_SUCCESS;
int rv = NSS_STATUS_SUCCESS;
+ ldapinit_mutex_lock();
if (ctxt->server || !ctxt->uris) {
- ret = do_connect(logopt, ldap, ctxt->server, ctxt);
+ ret = do_connect(logopt, conn, ctxt->server, ctxt);
#ifdef WITH_SASL
/* Dispose of the sasl authentication connection and try again. */
if (ctxt->auth_required & LDAP_NEED_AUTH &&
ret != NSS_STATUS_SUCCESS && ret != NSS_STATUS_NOTFOUND) {
- ldapinit_mutex_lock();
- autofs_sasl_dispose(*ldap, ctxt);
- ldapinit_mutex_unlock();
- ret = connect_to_server(logopt, ldap,
+ autofs_sasl_dispose(conn, ctxt);
+ ret = connect_to_server(logopt, conn,
ctxt->server, ctxt);
}
#endif
+ ldapinit_mutex_unlock();
return ret;
}
if (ctxt->dclist) {
- dcrv = find_dc_server(logopt, ldap, ctxt->dclist->uri, ctxt);
- if (dcrv == NSS_STATUS_SUCCESS)
+ dcrv = find_dc_server(logopt, conn, ctxt->dclist->uri, ctxt);
+ if (dcrv == NSS_STATUS_SUCCESS) {
+ ldapinit_mutex_unlock();
return dcrv;
+ }
}
uris_mutex_lock(ctxt);
if (ctxt->dclist) {
- if (!ldap || ctxt->dclist->expire < time(NULL)) {
+ if (!conn->ldap || ctxt->dclist->expire < time(NULL)) {
free_dclist(ctxt->dclist);
ctxt->dclist = NULL;
}
@@ -1009,7 +1004,7 @@ static int do_reconnect(unsigned logopt,
if (!ctxt->uri)
goto find_server;
- rv = do_connect(logopt, ldap, ctxt->uri->uri, ctxt);
+ rv = do_connect(logopt, conn, ctxt->uri->uri, ctxt);
#ifdef WITH_SASL
/*
* Dispose of the sasl authentication connection and try the
@@ -1017,26 +1012,24 @@ static int do_reconnect(unsigned logopt,
*/
if (ctxt->auth_required & LDAP_NEED_AUTH &&
rv != NSS_STATUS_SUCCESS && rv != NSS_STATUS_NOTFOUND) {
- ldapinit_mutex_lock();
- autofs_sasl_dispose(*ldap, ctxt);
- ldapinit_mutex_unlock();
- rv = connect_to_server(logopt, ldap, ctxt->uri->uri, ctxt);
+ autofs_sasl_dispose(conn, ctxt);
+ rv = connect_to_server(logopt, conn, ctxt->uri->uri, ctxt);
}
#endif
- if (rv == NSS_STATUS_SUCCESS)
+ if (rv == NSS_STATUS_SUCCESS) {
+ ldapinit_mutex_unlock();
return rv;
+ }
/* Failed to connect, try to find a new server */
find_server:
#ifdef WITH_SASL
- ldapinit_mutex_lock();
- autofs_sasl_dispose(*ldap, ctxt);
- ldapinit_mutex_unlock();
+ autofs_sasl_dispose(conn, ctxt);
#endif
/* Current server failed, try the rest or dc connection */
- ret = find_server(logopt, ldap, ctxt);
+ ret = find_server(logopt, conn, ctxt);
if (ret != NSS_STATUS_SUCCESS) {
if (ret == NSS_STATUS_NOTFOUND ||
dcrv == NSS_STATUS_NOTFOUND ||
@@ -1044,6 +1037,7 @@ find_server:
ret = NSS_STATUS_NOTFOUND;
error(logopt, MODPREFIX "failed to find available server");
}
+ ldapinit_mutex_unlock();
return ret;
}
@@ -1877,11 +1871,6 @@ int lookup_reinit(const char *mapfmt,
*context = new;
-#ifdef WITH_SASL
- ldapinit_mutex_lock();
- autofs_sasl_dispose(NULL, ctxt);
- ldapinit_mutex_unlock();
-#endif
free_context(ctxt);
return 0;
@@ -1893,6 +1882,8 @@ int lookup_read_master(struct master *ma
unsigned int timeout = master->default_timeout;
unsigned int logging = master->default_logging;
unsigned int logopt = master->logopt;
+ struct ldap_conn conn;
+ LDAP *ldap;
int rv, l, count;
char buf[MAX_ERR_BUF];
char parse_buf[PARSE_MAX_BUF];
@@ -1903,12 +1894,13 @@ int lookup_read_master(struct master *ma
char **values = NULL;
char *attrs[3];
int scope = LDAP_SCOPE_SUBTREE;
- LDAP *ldap = NULL;
/* Initialize the LDAP context. */
- rv = do_reconnect(logopt, &ldap, ctxt);
+ memset(&conn, 0, sizeof(struct ldap_conn));
+ rv = do_reconnect(logopt, &conn, ctxt);
if (rv)
return rv;
+ ldap = conn.ldap;
class = ctxt->schema->entry_class;
entry = ctxt->schema->entry_attr;
@@ -1942,7 +1934,7 @@ int lookup_read_master(struct master *ma
if ((rv != LDAP_SUCCESS) || !result) {
error(logopt, MODPREFIX "query failed for %s: %s",
query, ldap_err2string(rv));
- unbind_ldap_connection(logging, ldap, ctxt);
+ unbind_ldap_connection(logging, &conn, ctxt);
if (result)
ldap_msgfree(result);
free(query);
@@ -1955,7 +1947,7 @@ int lookup_read_master(struct master *ma
MODPREFIX "query succeeded, no matches for %s",
query);
ldap_msgfree(result);
- unbind_ldap_connection(logging, ldap, ctxt);
+ unbind_ldap_connection(logging, &conn, ctxt);
free(query);
return NSS_STATUS_NOTFOUND;
} else
@@ -2076,7 +2068,7 @@ next:
/* Clean up. */
ldap_msgfree(result);
- unbind_ldap_connection(logopt, ldap, ctxt);
+ unbind_ldap_connection(logopt, &conn, ctxt);
free(query);
return NSS_STATUS_SUCCESS;
@@ -2796,6 +2788,7 @@ static int read_one_map(struct autofs_po
struct lookup_context *ctxt,
time_t age, int *result_ldap)
{
+ struct ldap_conn conn;
struct ldap_search_params sp;
char buf[MAX_ERR_BUF];
char *class, *info, *entry;
@@ -2816,10 +2809,11 @@ static int read_one_map(struct autofs_po
sp.age = age;
/* Initialize the LDAP context. */
- sp.ldap = NULL;
- rv = do_reconnect(ap->logopt, &sp.ldap, ctxt);
+ memset(&conn, 0, sizeof(struct ldap_conn));
+ rv = do_reconnect(ap->logopt, &conn, ctxt);
if (rv)
return rv;
+ sp.ldap = conn.ldap;
class = ctxt->schema->entry_class;
entry = ctxt->schema->entry_attr;
@@ -2878,7 +2872,7 @@ static int read_one_map(struct autofs_po
if (sp.pageSize < 5) {
debug(ap->logopt, MODPREFIX
"result size too small");
- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
*result_ldap = rv;
free(sp.query);
return NSS_STATUS_UNAVAIL;
@@ -2887,7 +2881,7 @@ static int read_one_map(struct autofs_po
}
if (rv != LDAP_SUCCESS || !sp.result) {
- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
*result_ldap = rv;
if (sp.result)
ldap_msgfree(sp.result);
@@ -2903,7 +2897,7 @@ static int read_one_map(struct autofs_po
rv = do_get_entries(&sp, source, ctxt);
if (rv != LDAP_SUCCESS) {
ldap_msgfree(sp.result);
- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
*result_ldap = rv;
if (sp.cookie)
ber_bvfree(sp.cookie);
@@ -2916,7 +2910,7 @@ static int read_one_map(struct autofs_po
debug(ap->logopt, MODPREFIX "done updating map");
- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
source->age = age;
if (sp.cookie)
@@ -2959,6 +2953,8 @@ static int lookup_one(struct autofs_poin
char *qKey, int qKey_len, struct lookup_context *ctxt)
{
struct mapent_cache *mc;
+ struct ldap_conn conn;
+ LDAP *ldap;
int rv, i, l, ql, count;
char buf[MAX_ERR_BUF];
time_t age = time(NULL);
@@ -2971,7 +2967,6 @@ static int lookup_one(struct autofs_poin
struct berval **bvValues;
char *attrs[3];
int scope = LDAP_SCOPE_SUBTREE;
- LDAP *ldap = NULL;
struct mapent *we;
unsigned int wild = 0;
int ret = CHE_MISSING;
@@ -2984,11 +2979,13 @@ static int lookup_one(struct autofs_poin
}
/* Initialize the LDAP context. */
- rv = do_reconnect(ap->logopt, &ldap, ctxt);
+ memset(&conn, 0, sizeof(struct ldap_conn));
+ rv = do_reconnect(ap->logopt, &conn, ctxt);
if (rv == NSS_STATUS_UNAVAIL)
return CHE_UNAVAIL;
if (rv == NSS_STATUS_NOTFOUND)
return ret;
+ ldap = conn.ldap;
class = ctxt->schema->entry_class;
entry = ctxt->schema->entry_attr;
@@ -3076,7 +3073,7 @@ static int lookup_one(struct autofs_poin
if ((rv != LDAP_SUCCESS) || !result) {
crit(ap->logopt, MODPREFIX "query failed for %s", query);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
if (result)
ldap_msgfree(result);
free(query);
@@ -3091,7 +3088,7 @@ static int lookup_one(struct autofs_poin
debug(ap->logopt,
MODPREFIX "got answer, but no entry for %s", query);
ldap_msgfree(result);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
free(query);
return CHE_MISSING;
}
@@ -3277,7 +3274,7 @@ next:
}
ldap_msgfree(result);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
/* Failed to find wild entry, update cache if needed */
cache_writelock(mc);
@@ -3317,7 +3314,8 @@ static int lookup_one_amd(struct autofs_
struct lookup_context *ctxt)
{
struct mapent_cache *mc = source->mc;
- LDAP *ldap = NULL;
+ struct ldap_conn conn;
+ LDAP *ldap;
LDAPMessage *result = NULL, *e;
char *query;
int scope = LDAP_SCOPE_SUBTREE;
@@ -3336,11 +3334,13 @@ static int lookup_one_amd(struct autofs_
}
/* Initialize the LDAP context. */
- rv = do_reconnect(ap->logopt, &ldap, ctxt);
+ memset(&conn, 0, sizeof(struct ldap_conn));
+ rv = do_reconnect(ap->logopt, &conn, ctxt);
if (rv == NSS_STATUS_UNAVAIL)
return CHE_UNAVAIL;
if (rv == NSS_STATUS_NOTFOUND)
return ret;
+ ldap = conn.ldap;
map = ctxt->schema->map_attr;
class = ctxt->schema->entry_class;
@@ -3382,7 +3382,7 @@ static int lookup_one_amd(struct autofs_
rv = ldap_search_s(ldap, ctxt->base, scope, query, attrs, 0, &result);
if ((rv != LDAP_SUCCESS) || !result) {
crit(ap->logopt, MODPREFIX "query failed for %s", query);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
if (result)
ldap_msgfree(result);
free(query);
@@ -3397,7 +3397,7 @@ static int lookup_one_amd(struct autofs_
debug(ap->logopt,
MODPREFIX "got answer, but no entry for %s", query);
ldap_msgfree(result);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
free(query);
return CHE_MISSING;
}
@@ -3459,7 +3459,7 @@ next:
}
ldap_msgfree(result);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
free(query);
return ret;