|
Ian Kent |
c5187b |
autofs-5.0.4 - uris list locking fix
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
From: Ian Kent <raven@themaw.net>
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
The ldap uris list doesn't need to change we just need to keep
|
|
Ian Kent |
c5187b |
track of current server uri in the list and try to connect in
|
|
Ian Kent |
c5187b |
a round robin order. Also it's possible multiple concurrent
|
|
Ian Kent |
c5187b |
connection attempts may not be able to use the full list of
|
|
Ian Kent |
c5187b |
servers (if one is present).
|
|
Ian Kent |
c5187b |
---
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
CHANGELOG | 1 +
|
|
Ian Kent |
c5187b |
include/lookup_ldap.h | 3 +-
|
|
Ian Kent |
c5187b |
modules/lookup_ldap.c | 68 ++++++++++++++++++++++---------------------------
|
|
Ian Kent |
c5187b |
3 files changed, 33 insertions(+), 39 deletions(-)
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
diff --git a/CHANGELOG b/CHANGELOG
|
|
Ian Kent |
c5187b |
index 3199e4d..b093451 100644
|
|
Ian Kent |
c5187b |
--- a/CHANGELOG
|
|
Ian Kent |
c5187b |
+++ b/CHANGELOG
|
|
Ian Kent |
c5187b |
@@ -10,6 +10,7 @@
|
|
Ian Kent |
c5187b |
- clear the quoted flag after each character from program map input.
|
|
Ian Kent |
c5187b |
- use CLOEXEC flag for setmntent also.
|
|
Ian Kent |
c5187b |
- fix hosts map use after free.
|
|
Ian Kent |
c5187b |
+- fix uri list locking (again).
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
4/11/2008 autofs-5.0.4
|
|
Ian Kent |
c5187b |
-----------------------
|
|
Ian Kent |
c5187b |
diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
|
|
Ian Kent |
c5187b |
index f9ed778..b47bf5d 100644
|
|
Ian Kent |
c5187b |
--- a/include/lookup_ldap.h
|
|
Ian Kent |
c5187b |
+++ b/include/lookup_ldap.h
|
|
Ian Kent |
c5187b |
@@ -55,7 +55,8 @@ struct lookup_context {
|
|
Ian Kent |
c5187b |
* given in configuration.
|
|
Ian Kent |
c5187b |
*/
|
|
Ian Kent |
c5187b |
pthread_mutex_t uris_mutex;
|
|
Ian Kent |
c5187b |
- struct list_head *uri;
|
|
Ian Kent |
c5187b |
+ struct list_head *uris;
|
|
Ian Kent |
c5187b |
+ struct ldap_uri *uri;
|
|
Ian Kent |
c5187b |
char *cur_host;
|
|
Ian Kent |
c5187b |
struct ldap_searchdn *sdns;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
|
Ian Kent |
c5187b |
index 6ba80eb..b6784e1 100644
|
|
Ian Kent |
c5187b |
--- a/modules/lookup_ldap.c
|
|
Ian Kent |
c5187b |
+++ b/modules/lookup_ldap.c
|
|
Ian Kent |
c5187b |
@@ -137,7 +137,7 @@ static void uris_mutex_unlock(struct lookup_context *ctxt)
|
|
Ian Kent |
c5187b |
return;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
-int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
|
|
Ian Kent |
c5187b |
+int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt)
|
|
Ian Kent |
c5187b |
{
|
|
Ian Kent |
c5187b |
int rv;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
@@ -147,16 +147,14 @@ int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt
|
|
Ian Kent |
c5187b |
rv = ldap_simple_bind_s(ldap, NULL, NULL);
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
if (rv != LDAP_SUCCESS) {
|
|
Ian Kent |
c5187b |
- if (!ctxt->uri) {
|
|
Ian Kent |
c5187b |
+ if (!ctxt->uris) {
|
|
Ian Kent |
c5187b |
crit(logopt, MODPREFIX
|
|
Ian Kent |
c5187b |
"Unable to bind to the LDAP server: "
|
|
Ian Kent |
c5187b |
"%s, error %s", ctxt->server ? "" : "(default)",
|
|
Ian Kent |
c5187b |
ldap_err2string(rv));
|
|
Ian Kent |
c5187b |
} else {
|
|
Ian Kent |
c5187b |
- struct ldap_uri *uri;
|
|
Ian Kent |
c5187b |
- uri = list_entry(ctxt->uri->next, struct ldap_uri, list);
|
|
Ian Kent |
c5187b |
info(logopt, MODPREFIX "Unable to bind to the LDAP server: "
|
|
Ian Kent |
c5187b |
- "%s, error %s", uri->uri, ldap_err2string(rv));
|
|
Ian Kent |
c5187b |
+ "%s, error %s", uri, ldap_err2string(rv));
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
return -1;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
@@ -498,7 +496,7 @@ static int find_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctx
|
|
Ian Kent |
c5187b |
return 0;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
-static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
|
|
Ian Kent |
c5187b |
+static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt)
|
|
Ian Kent |
c5187b |
{
|
|
Ian Kent |
c5187b |
char *host = NULL, *nhost;
|
|
Ian Kent |
c5187b |
int rv, need_base = 1;
|
|
Ian Kent |
c5187b |
@@ -511,11 +509,11 @@ static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
|
|
Ian Kent |
c5187b |
rv = autofs_sasl_bind(logopt, ldap, ctxt);
|
|
Ian Kent |
c5187b |
debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
|
|
Ian Kent |
c5187b |
} else {
|
|
Ian Kent |
c5187b |
- rv = bind_ldap_anonymous(logopt, ldap, ctxt);
|
|
Ian Kent |
c5187b |
+ rv = bind_ldap_anonymous(logopt, ldap, uri, ctxt);
|
|
Ian Kent |
c5187b |
debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv);
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
#else
|
|
Ian Kent |
c5187b |
- rv = bind_ldap_anonymous(logopt, ldap, ctxt);
|
|
Ian Kent |
c5187b |
+ rv = bind_ldap_anonymous(logopt, ldap, uri, ctxt);
|
|
Ian Kent |
c5187b |
debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv);
|
|
Ian Kent |
c5187b |
#endif
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
@@ -584,7 +582,7 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context
|
|
Ian Kent |
c5187b |
if (!ldap)
|
|
Ian Kent |
c5187b |
return NULL;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
- if (!do_bind(logopt, ldap, ctxt)) {
|
|
Ian Kent |
c5187b |
+ if (!do_bind(logopt, ldap, uri, ctxt)) {
|
|
Ian Kent |
c5187b |
unbind_ldap_connection(logopt, ldap, ctxt);
|
|
Ian Kent |
c5187b |
return NULL;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
@@ -612,7 +610,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c
|
|
Ian Kent |
c5187b |
return NULL;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
- if (!do_bind(logopt, ldap, ctxt)) {
|
|
Ian Kent |
c5187b |
+ if (!do_bind(logopt, ldap, uri, ctxt)) {
|
|
Ian Kent |
c5187b |
unbind_ldap_connection(logopt, ldap, ctxt);
|
|
Ian Kent |
c5187b |
autofs_sasl_dispose(ctxt);
|
|
Ian Kent |
c5187b |
error(logopt, MODPREFIX "cannot bind to server");
|
|
Ian Kent |
c5187b |
@@ -638,36 +636,34 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
|
|
Ian Kent |
c5187b |
{
|
|
Ian Kent |
c5187b |
LDAP *ldap = NULL;
|
|
Ian Kent |
c5187b |
struct ldap_uri *this;
|
|
Ian Kent |
c5187b |
- struct list_head *p;
|
|
Ian Kent |
c5187b |
- LIST_HEAD(tmp);
|
|
Ian Kent |
c5187b |
+ struct list_head *p, *first;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
/* Try each uri in list, add connect fails to tmp list */
|
|
Ian Kent |
c5187b |
uris_mutex_lock(ctxt);
|
|
Ian Kent |
c5187b |
- p = ctxt->uri->next;
|
|
Ian Kent |
c5187b |
- while(p != ctxt->uri) {
|
|
Ian Kent |
c5187b |
+ if (!ctxt->uri)
|
|
Ian Kent |
c5187b |
+ first = ctxt->uris;
|
|
Ian Kent |
c5187b |
+ else
|
|
Ian Kent |
c5187b |
+ first = &ctxt->uri->list;
|
|
Ian Kent |
c5187b |
+ uris_mutex_unlock(ctxt);
|
|
Ian Kent |
c5187b |
+ p = first->next;
|
|
Ian Kent |
c5187b |
+ while(p != first) {
|
|
Ian Kent |
c5187b |
+ /* Skip list head */
|
|
Ian Kent |
c5187b |
+ if (p == ctxt->uris) {
|
|
Ian Kent |
c5187b |
+ p = p->next;
|
|
Ian Kent |
c5187b |
+ continue;
|
|
Ian Kent |
c5187b |
+ }
|
|
Ian Kent |
c5187b |
this = list_entry(p, struct ldap_uri, list);
|
|
Ian Kent |
c5187b |
- uris_mutex_unlock(ctxt);
|
|
Ian Kent |
c5187b |
debug(logopt, "trying server %s", this->uri);
|
|
Ian Kent |
c5187b |
ldap = connect_to_server(logopt, this->uri, ctxt);
|
|
Ian Kent |
c5187b |
if (ldap) {
|
|
Ian Kent |
c5187b |
info(logopt, "connected to uri %s", this->uri);
|
|
Ian Kent |
c5187b |
uris_mutex_lock(ctxt);
|
|
Ian Kent |
c5187b |
+ ctxt->uri = this;
|
|
Ian Kent |
c5187b |
+ uris_mutex_unlock(ctxt);
|
|
Ian Kent |
c5187b |
break;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
- uris_mutex_lock(ctxt);
|
|
Ian Kent |
c5187b |
p = p->next;
|
|
Ian Kent |
c5187b |
- list_del_init(&this->list);
|
|
Ian Kent |
c5187b |
- list_add_tail(&this->list, &tmp);
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
- /*
|
|
Ian Kent |
c5187b |
- * Successfuly connected uri (head of list) and untried uris are
|
|
Ian Kent |
c5187b |
- * in ctxt->uri list. Make list of remainder and failed uris with
|
|
Ian Kent |
c5187b |
- * failed uris at end and assign back to ctxt-uri.
|
|
Ian Kent |
c5187b |
- */
|
|
Ian Kent |
c5187b |
- list_splice(ctxt->uri, &tmp);
|
|
Ian Kent |
c5187b |
- INIT_LIST_HEAD(ctxt->uri);
|
|
Ian Kent |
c5187b |
- list_splice(&tmp, ctxt->uri);
|
|
Ian Kent |
c5187b |
- uris_mutex_unlock(ctxt);
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
return ldap;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
@@ -677,23 +673,19 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
|
|
Ian Kent |
c5187b |
struct ldap_uri *this;
|
|
Ian Kent |
c5187b |
LDAP *ldap;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
- if (ctxt->server || !ctxt->uri) {
|
|
Ian Kent |
c5187b |
+ if (ctxt->server || !ctxt->uris) {
|
|
Ian Kent |
c5187b |
ldap = do_connect(logopt, ctxt->server, ctxt);
|
|
Ian Kent |
c5187b |
return ldap;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
uris_mutex_lock(ctxt);
|
|
Ian Kent |
c5187b |
- this = list_entry(ctxt->uri->next, struct ldap_uri, list);
|
|
Ian Kent |
c5187b |
+ this = ctxt->uri;
|
|
Ian Kent |
c5187b |
uris_mutex_unlock(ctxt);
|
|
Ian Kent |
c5187b |
ldap = do_connect(logopt, this->uri, ctxt);
|
|
Ian Kent |
c5187b |
if (ldap)
|
|
Ian Kent |
c5187b |
return ldap;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
- /* Failed to connect, put at end of list */
|
|
Ian Kent |
c5187b |
- uris_mutex_lock(ctxt);
|
|
Ian Kent |
c5187b |
- list_del_init(&this->list);
|
|
Ian Kent |
c5187b |
- list_add_tail(&this->list, ctxt->uri);
|
|
Ian Kent |
c5187b |
- uris_mutex_unlock(ctxt);
|
|
Ian Kent |
c5187b |
+ /* Failed to connect, try to find a new server */
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
#ifdef WITH_SASL
|
|
Ian Kent |
c5187b |
autofs_sasl_dispose(ctxt);
|
|
Ian Kent |
c5187b |
@@ -1259,8 +1251,8 @@ static void free_context(struct lookup_context *ctxt)
|
|
Ian Kent |
c5187b |
free(ctxt->cur_host);
|
|
Ian Kent |
c5187b |
if (ctxt->base)
|
|
Ian Kent |
c5187b |
free(ctxt->base);
|
|
Ian Kent |
c5187b |
- if (ctxt->uri)
|
|
Ian Kent |
c5187b |
- defaults_free_uris(ctxt->uri);
|
|
Ian Kent |
c5187b |
+ if (ctxt->uris)
|
|
Ian Kent |
c5187b |
+ defaults_free_uris(ctxt->uris);
|
|
Ian Kent |
c5187b |
ret = pthread_mutex_destroy(&ctxt->uris_mutex);
|
|
Ian Kent |
c5187b |
if (ret)
|
|
Ian Kent |
c5187b |
fatal(ret);
|
|
Ian Kent |
c5187b |
@@ -1344,7 +1336,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
|
Ian Kent |
c5187b |
if (uris) {
|
|
Ian Kent |
c5187b |
validate_uris(uris);
|
|
Ian Kent |
c5187b |
if (!list_empty(uris))
|
|
Ian Kent |
c5187b |
- ctxt->uri = uris;
|
|
Ian Kent |
c5187b |
+ ctxt->uris = uris;
|
|
Ian Kent |
c5187b |
else {
|
|
Ian Kent |
c5187b |
error(LOGOPT_ANY,
|
|
Ian Kent |
c5187b |
"no valid uris found in config list"
|
|
Ian Kent |
c5187b |
@@ -1375,7 +1367,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
#endif
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
- if (ctxt->server || !ctxt->uri) {
|
|
Ian Kent |
c5187b |
+ if (ctxt->server || !ctxt->uris) {
|
|
Ian Kent |
c5187b |
ldap = connect_to_server(LOGOPT_NONE, ctxt->server, ctxt);
|
|
Ian Kent |
c5187b |
if (!ldap) {
|
|
Ian Kent |
c5187b |
free_context(ctxt);
|