]>
Commit | Line | Data |
---|---|---|
e5fd101c PS |
1 | autofs-5.0.4 - uris list locking fix |
2 | ||
3 | From: Ian Kent <raven@themaw.net> | |
4 | ||
5 | The ldap uris list doesn't need to change we just need to keep | |
6 | track of current server uri in the list and try to connect in | |
7 | a round robin order. Also it's possible multiple concurrent | |
8 | connection attempts may not be able to use the full list of | |
9 | servers (if one is present). | |
10 | --- | |
11 | ||
12 | CHANGELOG | 1 + | |
13 | include/lookup_ldap.h | 3 +- | |
14 | modules/lookup_ldap.c | 68 ++++++++++++++++++++++--------------------------- | |
15 | 3 files changed, 33 insertions(+), 39 deletions(-) | |
16 | ||
17 | ||
18 | diff --git a/CHANGELOG b/CHANGELOG | |
19 | index 3199e4d..b093451 100644 | |
20 | --- a/CHANGELOG | |
21 | +++ b/CHANGELOG | |
22 | @@ -10,6 +10,7 @@ | |
23 | - clear the quoted flag after each character from program map input. | |
24 | - use CLOEXEC flag for setmntent also. | |
25 | - fix hosts map use after free. | |
26 | +- fix uri list locking (again). | |
27 | ||
28 | 4/11/2008 autofs-5.0.4 | |
29 | ----------------------- | |
30 | diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h | |
31 | index f9ed778..b47bf5d 100644 | |
32 | --- a/include/lookup_ldap.h | |
33 | +++ b/include/lookup_ldap.h | |
34 | @@ -55,7 +55,8 @@ struct lookup_context { | |
35 | * given in configuration. | |
36 | */ | |
37 | pthread_mutex_t uris_mutex; | |
38 | - struct list_head *uri; | |
39 | + struct list_head *uris; | |
40 | + struct ldap_uri *uri; | |
41 | char *cur_host; | |
42 | struct ldap_searchdn *sdns; | |
43 | ||
44 | diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c | |
45 | index 6ba80eb..b6784e1 100644 | |
46 | --- a/modules/lookup_ldap.c | |
47 | +++ b/modules/lookup_ldap.c | |
48 | @@ -137,7 +137,7 @@ static void uris_mutex_unlock(struct lookup_context *ctxt) | |
49 | return; | |
50 | } | |
51 | ||
52 | -int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) | |
53 | +int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt) | |
54 | { | |
55 | int rv; | |
56 | ||
57 | @@ -147,16 +147,14 @@ int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt | |
58 | rv = ldap_simple_bind_s(ldap, NULL, NULL); | |
59 | ||
60 | if (rv != LDAP_SUCCESS) { | |
61 | - if (!ctxt->uri) { | |
62 | + if (!ctxt->uris) { | |
63 | crit(logopt, MODPREFIX | |
64 | "Unable to bind to the LDAP server: " | |
65 | "%s, error %s", ctxt->server ? "" : "(default)", | |
66 | ldap_err2string(rv)); | |
67 | } else { | |
68 | - struct ldap_uri *uri; | |
69 | - uri = list_entry(ctxt->uri->next, struct ldap_uri, list); | |
70 | info(logopt, MODPREFIX "Unable to bind to the LDAP server: " | |
71 | - "%s, error %s", uri->uri, ldap_err2string(rv)); | |
72 | + "%s, error %s", uri, ldap_err2string(rv)); | |
73 | } | |
74 | return -1; | |
75 | } | |
76 | @@ -498,7 +496,7 @@ static int find_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctx | |
77 | return 0; | |
78 | } | |
79 | ||
80 | -static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) | |
81 | +static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt) | |
82 | { | |
83 | char *host = NULL, *nhost; | |
84 | int rv, need_base = 1; | |
85 | @@ -511,11 +509,11 @@ static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) | |
86 | rv = autofs_sasl_bind(logopt, ldap, ctxt); | |
87 | debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv); | |
88 | } else { | |
89 | - rv = bind_ldap_anonymous(logopt, ldap, ctxt); | |
90 | + rv = bind_ldap_anonymous(logopt, ldap, uri, ctxt); | |
91 | debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv); | |
92 | } | |
93 | #else | |
94 | - rv = bind_ldap_anonymous(logopt, ldap, ctxt); | |
95 | + rv = bind_ldap_anonymous(logopt, ldap, uri, ctxt); | |
96 | debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv); | |
97 | #endif | |
98 | ||
99 | @@ -584,7 +582,7 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context | |
100 | if (!ldap) | |
101 | return NULL; | |
102 | ||
103 | - if (!do_bind(logopt, ldap, ctxt)) { | |
104 | + if (!do_bind(logopt, ldap, uri, ctxt)) { | |
105 | unbind_ldap_connection(logopt, ldap, ctxt); | |
106 | return NULL; | |
107 | } | |
108 | @@ -612,7 +610,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c | |
109 | return NULL; | |
110 | } | |
111 | ||
112 | - if (!do_bind(logopt, ldap, ctxt)) { | |
113 | + if (!do_bind(logopt, ldap, uri, ctxt)) { | |
114 | unbind_ldap_connection(logopt, ldap, ctxt); | |
115 | autofs_sasl_dispose(ctxt); | |
116 | error(logopt, MODPREFIX "cannot bind to server"); | |
117 | @@ -638,36 +636,34 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) | |
118 | { | |
119 | LDAP *ldap = NULL; | |
120 | struct ldap_uri *this; | |
121 | - struct list_head *p; | |
122 | - LIST_HEAD(tmp); | |
123 | + struct list_head *p, *first; | |
124 | ||
125 | /* Try each uri in list, add connect fails to tmp list */ | |
126 | uris_mutex_lock(ctxt); | |
127 | - p = ctxt->uri->next; | |
128 | - while(p != ctxt->uri) { | |
129 | + if (!ctxt->uri) | |
130 | + first = ctxt->uris; | |
131 | + else | |
132 | + first = &ctxt->uri->list; | |
133 | + uris_mutex_unlock(ctxt); | |
134 | + p = first->next; | |
135 | + while(p != first) { | |
136 | + /* Skip list head */ | |
137 | + if (p == ctxt->uris) { | |
138 | + p = p->next; | |
139 | + continue; | |
140 | + } | |
141 | this = list_entry(p, struct ldap_uri, list); | |
142 | - uris_mutex_unlock(ctxt); | |
143 | debug(logopt, "trying server %s", this->uri); | |
144 | ldap = connect_to_server(logopt, this->uri, ctxt); | |
145 | if (ldap) { | |
146 | info(logopt, "connected to uri %s", this->uri); | |
147 | uris_mutex_lock(ctxt); | |
148 | + ctxt->uri = this; | |
149 | + uris_mutex_unlock(ctxt); | |
150 | break; | |
151 | } | |
152 | - uris_mutex_lock(ctxt); | |
153 | p = p->next; | |
154 | - list_del_init(&this->list); | |
155 | - list_add_tail(&this->list, &tmp); | |
156 | } | |
157 | - /* | |
158 | - * Successfuly connected uri (head of list) and untried uris are | |
159 | - * in ctxt->uri list. Make list of remainder and failed uris with | |
160 | - * failed uris at end and assign back to ctxt-uri. | |
161 | - */ | |
162 | - list_splice(ctxt->uri, &tmp); | |
163 | - INIT_LIST_HEAD(ctxt->uri); | |
164 | - list_splice(&tmp, ctxt->uri); | |
165 | - uris_mutex_unlock(ctxt); | |
166 | ||
167 | return ldap; | |
168 | } | |
169 | @@ -677,23 +673,19 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) | |
170 | struct ldap_uri *this; | |
171 | LDAP *ldap; | |
172 | ||
173 | - if (ctxt->server || !ctxt->uri) { | |
174 | + if (ctxt->server || !ctxt->uris) { | |
175 | ldap = do_connect(logopt, ctxt->server, ctxt); | |
176 | return ldap; | |
177 | } | |
178 | ||
179 | uris_mutex_lock(ctxt); | |
180 | - this = list_entry(ctxt->uri->next, struct ldap_uri, list); | |
181 | + this = ctxt->uri; | |
182 | uris_mutex_unlock(ctxt); | |
183 | ldap = do_connect(logopt, this->uri, ctxt); | |
184 | if (ldap) | |
185 | return ldap; | |
186 | ||
187 | - /* Failed to connect, put at end of list */ | |
188 | - uris_mutex_lock(ctxt); | |
189 | - list_del_init(&this->list); | |
190 | - list_add_tail(&this->list, ctxt->uri); | |
191 | - uris_mutex_unlock(ctxt); | |
192 | + /* Failed to connect, try to find a new server */ | |
193 | ||
194 | #ifdef WITH_SASL | |
195 | autofs_sasl_dispose(ctxt); | |
196 | @@ -1259,8 +1251,8 @@ static void free_context(struct lookup_context *ctxt) | |
197 | free(ctxt->cur_host); | |
198 | if (ctxt->base) | |
199 | free(ctxt->base); | |
200 | - if (ctxt->uri) | |
201 | - defaults_free_uris(ctxt->uri); | |
202 | + if (ctxt->uris) | |
203 | + defaults_free_uris(ctxt->uris); | |
204 | ret = pthread_mutex_destroy(&ctxt->uris_mutex); | |
205 | if (ret) | |
206 | fatal(ret); | |
207 | @@ -1344,7 +1336,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co | |
208 | if (uris) { | |
209 | validate_uris(uris); | |
210 | if (!list_empty(uris)) | |
211 | - ctxt->uri = uris; | |
212 | + ctxt->uris = uris; | |
213 | else { | |
214 | error(LOGOPT_ANY, | |
215 | "no valid uris found in config list" | |
216 | @@ -1375,7 +1367,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co | |
217 | } | |
218 | #endif | |
219 | ||
220 | - if (ctxt->server || !ctxt->uri) { | |
221 | + if (ctxt->server || !ctxt->uris) { | |
222 | ldap = connect_to_server(LOGOPT_NONE, ctxt->server, ctxt); | |
223 | if (!ldap) { | |
224 | free_context(ctxt); |