]> git.pld-linux.org Git - packages/autofs.git/blame - autofs-5.0.2-add-multiple-server-selection-option.patch
- rel.1, lets try
[packages/autofs.git] / autofs-5.0.2-add-multiple-server-selection-option.patch
CommitLineData
3d551623
PG
1diff --git a/CHANGELOG b/CHANGELOG
2index 9a2a8c1..933b1a1 100644
3--- a/CHANGELOG
4+++ b/CHANGELOG
5@@ -27,6 +27,7 @@
6 - add SEARCH_BASE configuration option.
7 - work around segv at exit due to libxml2 tsd usage.
8 - re-read config on HUP signal.
9+- add LDAP_URI, LDAP_TIMEOUT and LDAP_NETWORK_TIMEOUT configuration options.
10
11 18/06/2007 autofs-5.0.2
12 -----------------------
13diff --git a/include/defaults.h b/include/defaults.h
14index 0984b1c..46393d9 100644
15--- a/include/defaults.h
16+++ b/include/defaults.h
17@@ -26,7 +26,8 @@
18 #define DEFAULT_BROWSE_MODE 1
19 #define DEFAULT_LOGGING 0
20
21-#define DEFAULT_LDAP_SERVER NULL
22+#define DEFAULT_LDAP_TIMEOUT -1
23+#define DEFAULT_LDAP_NETWORK_TIMEOUT 8
24
25 #define DEFAULT_MAP_OBJ_CLASS "nisMap"
26 #define DEFAULT_ENTRY_OBJ_CLASS "nisObject"
27@@ -46,6 +47,10 @@ unsigned int defaults_get_timeout(void);
28 unsigned int defaults_get_browse_mode(void);
29 unsigned int defaults_get_logging(void);
30 const char *defaults_get_ldap_server(void);
31+unsigned int defaults_get_ldap_timeout(void);
32+unsigned int defaults_get_ldap_network_timeout(void);
33+struct list_head *defaults_get_uris(void);
34+void defaults_free_uris(struct list_head *);
35 struct ldap_schema *defaults_get_default_schema(void);
36 struct ldap_schema *defaults_get_schema(void);
37 struct ldap_searchdn *defaults_get_searchdns(void);
38diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
39index 1a924be..ca8d658 100644
40--- a/include/lookup_ldap.h
41+++ b/include/lookup_ldap.h
42@@ -18,6 +18,11 @@ struct ldap_schema {
43 char *value_attr;
44 };
45
46+struct ldap_uri {
47+ char *uri;
48+ struct list_head list;
49+};
50+
51 struct ldap_searchdn {
52 char *basedn;
53 struct ldap_searchdn *next;
54@@ -30,6 +35,8 @@ struct lookup_context {
55 int port;
56 char *base;
57 char *qdn;
58+ unsigned int timeout;
59+ unsigned int network_timeout;
60
61 /* LDAP version 2 or 3 */
62 int version;
63@@ -37,7 +44,17 @@ struct lookup_context {
64 /* LDAP lookup configuration */
65 struct ldap_schema *schema;
66
67- /* List of base dns for searching */
68+ /*
69+ * List of servers and base dns for searching.
70+ * uri is the list of servers to attempt connection to and is
71+ * used only if server, above, is NULL. The head of the list
72+ * is the server which we are currently connected to.
73+ * cur_host tracks chnages to connected server, triggering
74+ * a scan of basedns when it changes.
75+ * sdns is the list of basdns to check, done in the order
76+ * given in configuration.
77+ */
78+ struct list_head *uri;
79 char *cur_host;
80 struct ldap_searchdn *sdns;
81
82@@ -77,7 +94,7 @@ struct lookup_context {
83 #define LDAP_AUTH_AUTODETECT 0x0004
84
85 /* lookup_ldap.c */
86-LDAP *init_ldap_connection(struct lookup_context *ctxt);
87+LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt);
88 int unbind_ldap_connection(LDAP *ldap, struct lookup_context *ctxt);
89 int authtype_requires_creds(const char *authtype);
90
91diff --git a/lib/defaults.c b/lib/defaults.c
92index 7da4631..bf1ceed 100644
93--- a/lib/defaults.c
94+++ b/lib/defaults.c
95@@ -17,6 +17,7 @@
96 #include <ctype.h>
97 #include <string.h>
98
99+#include "list.h"
100 #include "defaults.h"
101 #include "lookup_ldap.h"
102 #include "log.h"
103@@ -30,7 +31,9 @@
104 #define ENV_NAME_BROWSE_MODE "BROWSE_MODE"
105 #define ENV_NAME_LOGGING "LOGGING"
106
107-#define ENV_LDAP_SERVER "LDAP_SERVER"
108+#define LDAP_URI "LDAP_URI"
109+#define ENV_LDAP_TIMEOUT "LDAP_TIMEOUT"
110+#define ENV_LDAP_NETWORK_TIMEOUT "LDAP_NETWORK_TIMEOUT"
111
112 #define SEARCH_BASE "SEARCH_BASE"
113
114@@ -44,7 +47,6 @@
115 #define ENV_AUTH_CONF_FILE "AUTH_CONF_FILE"
116
117 static const char *default_master_map_name = DEFAULT_MASTER_MAP_NAME;
118-static const char *default_ldap_server = DEFAULT_LDAP_SERVER;
119 static const char *default_auth_conf_file = DEFAULT_AUTH_CONF_FILE;
120
121 static char *get_env_string(const char *name)
122@@ -178,6 +180,99 @@ static int parse_line(char *line, char **res, char **value)
123 return 1;
124 }
125
126+void defaults_free_uris(struct list_head *list)
127+{
128+ struct list_head *next;
129+ struct ldap_uri *uri;
130+
131+ if (list_empty(list)) {
132+ free(list);
133+ return;
134+ }
135+
136+ next = list->next;
137+ while (next != list) {
138+ uri = list_entry(next, struct ldap_uri, list);
139+ next = next->next;
140+ list_del(&uri->list);
141+ free(uri->uri);
142+ free(uri);
143+ }
144+ free(list);
145+
146+ return;
147+}
148+
149+static unsigned int add_uris(char *value, struct list_head *list)
150+{
151+ char *str, *tok, *ptr = NULL;
152+ size_t len = strlen(value);
153+
154+ str = alloca(len);
155+ if (!str)
156+ return 0;
157+ strcpy(str, value);
158+
159+ tok = strtok_r(str, " ", &ptr);
160+ while (tok) {
161+ struct ldap_uri *new;
162+ char *uri;
163+
164+ new = malloc(sizeof(struct ldap_uri));
165+ if (!new)
166+ continue;
167+
168+ uri = strdup(tok);
169+ if (!uri)
170+ free(new);
171+ else {
172+ new->uri = uri;
173+ list_add_tail(&new->list, list);
174+ }
175+
176+ tok = strtok_r(NULL, " ", &ptr);
177+ }
178+
179+ return 1;
180+}
181+
182+struct list_head *defaults_get_uris(void)
183+{
184+ FILE *f;
185+ char buf[MAX_LINE_LEN];
186+ char *res;
187+ struct list_head *list;
188+
189+ f = fopen(DEFAULTS_CONFIG_FILE, "r");
190+ if (!f)
191+ return NULL;
192+
193+ list = malloc(sizeof(struct list_head));
194+ if (!list) {
195+ fclose(f);
196+ return NULL;
197+ }
198+ INIT_LIST_HEAD(list);
199+
200+ while ((res = fgets(buf, MAX_LINE_LEN, f))) {
201+ char *key, *value;
202+
203+ if (!parse_line(res, &key, &value))
204+ continue;
205+
206+ if (!strcasecmp(res, LDAP_URI))
207+ add_uris(value, list);
208+ }
209+
210+ if (list_empty(list)) {
211+ free(list);
212+ list = NULL;
213+ }
214+
215+ fclose(f);
216+ return list;
217+}
218+
219 /*
220 * Read config env variables and check they have been set.
221 *
222@@ -205,7 +300,8 @@ unsigned int defaults_read_config(void)
223 check_set_config_value(key, ENV_NAME_TIMEOUT, value) ||
224 check_set_config_value(key, ENV_NAME_BROWSE_MODE, value) ||
225 check_set_config_value(key, ENV_NAME_LOGGING, value) ||
226- check_set_config_value(key, ENV_LDAP_SERVER, value) ||
227+ check_set_config_value(key, ENV_LDAP_TIMEOUT, value) ||
228+ check_set_config_value(key, ENV_LDAP_NETWORK_TIMEOUT, value) ||
229 check_set_config_value(key, ENV_NAME_MAP_OBJ_CLASS, value) ||
230 check_set_config_value(key, ENV_NAME_ENTRY_OBJ_CLASS, value) ||
231 check_set_config_value(key, ENV_NAME_MAP_ATTR, value) ||
232@@ -284,15 +380,26 @@ unsigned int defaults_get_logging(void)
233 return logging;
234 }
235
236-const char *defaults_get_ldap_server(void)
237+unsigned int defaults_get_ldap_timeout(void)
238 {
239- char *server;
240+ int res;
241
242- server = get_env_string(ENV_LDAP_SERVER);
243- if (!server)
244- return default_ldap_server;
245+ res = get_env_number(ENV_LDAP_TIMEOUT);
246+ if (res < 0)
247+ res = DEFAULT_LDAP_TIMEOUT;
248
249- return (const char *) server;
250+ return res;
251+}
252+
253+unsigned int defaults_get_ldap_network_timeout(void)
254+{
255+ int res;
256+
257+ res = get_env_number(ENV_LDAP_NETWORK_TIMEOUT);
258+ if (res < 0)
259+ res = DEFAULT_LDAP_NETWORK_TIMEOUT;
260+
261+ return res;
262 }
263
264 struct ldap_schema *defaults_get_default_schema(void)
265diff --git a/man/auto.master.5.in b/man/auto.master.5.in
266index 0cb2f07..68447e0 100644
267--- a/man/auto.master.5.in
268+++ b/man/auto.master.5.in
269@@ -230,10 +230,27 @@ values must be set, any partial schema specification will be ignored.
270 .P
271 The configuration settings available are:
272 .TP
273+.B LDAP_TIMEOUT
274+Set the network response timeout (default 8).
275+Set timeout value for the synchronous API calls. The default is the LDAP
276+library default of an infinite timeout.
277+.TP
278+.B LDAP_NETWORK_TIMEOUT
279+Set the network response timeout (default 8).
280+.TP
281+.B LDAP_URI
282+A space seperated list of server uris of the form <proto>://<server>[/]
283+where <proto> can be ldap or ldaps. The option can be given multiple times.
284+Map entries that include a server name override this option and it is then
285+not used. Default is an empty list in which case either the server given
286+in a map entry or the LDAP configured default is used. This uri list is read at
287+startup and whenever the daemon receives a HUP signal.
288+.TP
289 .B SEARCH_BASE
290 The base dn to use when searching for amap base dn. This entry may be
291 given multiple times and each will be checked for a map base dn in
292-the order they occur in the configuration.
293+the order they occur in the configuration. The search base list is read
294+at startup and whenever the daemon recieves a HUP signal.
295 .TP
296 .B MAP_OBJECT_CLASS
297 The map object class. In the \fBnisMap\fP schema this corresponds to the class
298diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
299index 2baf8b8..4068561 100644
300--- a/modules/lookup_ldap.c
301+++ b/modules/lookup_ldap.c
302@@ -49,6 +49,8 @@ static struct ldap_schema common_schema[] = {
303 };
304 static unsigned int common_schema_count = sizeof(common_schema)/sizeof(struct ldap_schema);
305
306+static LDAP *auth_init(const char *, struct lookup_context *);
307+
308 int bind_ldap_anonymous(LDAP *ldap, struct lookup_context *ctxt)
309 {
310 int rv;
311@@ -59,10 +61,18 @@ int bind_ldap_anonymous(LDAP *ldap, struct lookup_context *ctxt)
312 rv = ldap_simple_bind_s(ldap, NULL, NULL);
313
314 if (rv != LDAP_SUCCESS) {
315- crit(LOGOPT_ANY,
316- MODPREFIX "Unable to bind to the LDAP server: "
317- "%s, error %s", ctxt->server ? "" : "(default)",
318- ldap_err2string(rv));
319+ if (!ctxt->uri) {
320+ crit(LOGOPT_ANY,
321+ MODPREFIX "Unable to bind to the LDAP server: "
322+ "%s, error %s", ctxt->server ? "" : "(default)",
323+ ldap_err2string(rv));
324+ } else {
325+ struct ldap_uri *uri;
326+ uri = list_entry(ctxt->uri->next, struct ldap_uri, list);
327+ warn(LOGOPT_ANY,
328+ MODPREFIX "Unable to bind to the LDAP server: "
329+ "%s, error %s", uri->uri, ldap_err2string(rv));
330+ }
331 return -1;
332 }
333
334@@ -98,20 +108,21 @@ int unbind_ldap_connection(LDAP *ldap, struct lookup_context *ctxt)
335 return rv;
336 }
337
338-LDAP *init_ldap_connection(struct lookup_context *ctxt)
339+LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt)
340 {
341 LDAP *ldap = NULL;
342- int timeout = 8;
343+ struct timeval timeout = { ctxt->timeout, 0 };
344+ struct timeval net_timeout = { ctxt->network_timeout, 0 };
345 int rv;
346
347 ctxt->version = 3;
348
349 /* Initialize the LDAP context. */
350- rv = ldap_initialize(&ldap, ctxt->server);
351+ rv = ldap_initialize(&ldap, uri);
352 if (rv != LDAP_OPT_SUCCESS) {
353 crit(LOGOPT_ANY,
354 MODPREFIX "couldn't initialize LDAP connection to %s",
355- ctxt->server ? ctxt->server : "default server");
356+ uri ? uri : "default server");
357 return NULL;
358 }
359
360@@ -120,7 +131,7 @@ LDAP *init_ldap_connection(struct lookup_context *ctxt)
361 if (rv != LDAP_OPT_SUCCESS) {
362 /* fall back to LDAPv2 */
363 ldap_unbind_ext(ldap, NULL, NULL);
364- rv = ldap_initialize(&ldap, ctxt->server);
365+ rv = ldap_initialize(&ldap, uri);
366 if (rv != LDAP_OPT_SUCCESS) {
367 crit(LOGOPT_ANY, MODPREFIX "couldn't initialize LDAP");
368 return NULL;
369@@ -128,12 +139,22 @@ LDAP *init_ldap_connection(struct lookup_context *ctxt)
370 ctxt->version = 2;
371 }
372
373- /* Sane network connection timeout */
374- rv = ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
375+
376+ if (ctxt->timeout != -1) {
377+ /* Set synchronous call timeout */
378+ rv = ldap_set_option(ldap, LDAP_OPT_TIMEOUT, &timeout);
379+ if (rv != LDAP_OPT_SUCCESS)
380+ info(LOGOPT_ANY, MODPREFIX
381+ "failed to set synchronous call timeout to %d",
382+ timeout.tv_sec);
383+ }
384+
385+ /* Sane network timeout */
386+ rv = ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &net_timeout);
387 if (rv != LDAP_OPT_SUCCESS)
388 info(LOGOPT_ANY,
389 MODPREFIX "failed to set connection timeout to %d",
390- timeout);
391+ net_timeout.tv_sec);
392
393 #ifdef WITH_SASL
394 if (ctxt->use_tls) {
395@@ -159,7 +180,7 @@ LDAP *init_ldap_connection(struct lookup_context *ctxt)
396 return NULL;
397 }
398 ctxt->use_tls = LDAP_TLS_DONT_USE;
399- ldap = init_ldap_connection(ctxt);
400+ ldap = init_ldap_connection(uri, ctxt);
401 if (ldap)
402 ctxt->use_tls = LDAP_TLS_INIT;
403 return ldap;
404@@ -271,7 +292,7 @@ static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *cla
405 e = ldap_first_entry(ldap, result);
406 if (e) {
407 dn = ldap_get_dn(ldap, e);
408- debug(LOGOPT_NONE, MODPREFIX "query dn %s", dn);
409+ debug(LOGOPT_NONE, MODPREFIX "found query dn %s", dn);
410 } else {
411 debug(LOGOPT_NONE,
412 MODPREFIX "query succeeded, no matches for %s",
413@@ -378,16 +399,11 @@ static int find_query_dn(LDAP *ldap, struct lookup_context *ctxt)
414 return 0;
415 }
416
417-static LDAP *do_connect(struct lookup_context *ctxt)
418+static int do_bind(LDAP *ldap, struct lookup_context *ctxt)
419 {
420- LDAP *ldap;
421 char *host = NULL, *nhost;
422 int rv, need_base = 1;
423
424- ldap = init_ldap_connection(ctxt);
425- if (!ldap)
426- return NULL;
427-
428 #ifdef WITH_SASL
429 debug(LOGOPT_NONE, "auth_required: %d, sasl_mech %s",
430 ctxt->auth_required, ctxt->sasl_mech);
431@@ -407,23 +423,19 @@ static LDAP *do_connect(struct lookup_context *ctxt)
432 debug(LOGOPT_NONE, MODPREFIX "ldap anonymous bind returned %d", rv);
433 #endif
434
435- if (rv != 0) {
436- unbind_ldap_connection(ldap, ctxt);
437- return NULL;
438- }
439+ if (rv != 0)
440+ return 0;
441
442 rv = ldap_get_option(ldap, LDAP_OPT_HOST_NAME, &host);
443 if (rv != LDAP_SUCCESS || !host) {
444- unbind_ldap_connection(ldap, ctxt);
445 debug(LOGOPT_ANY, "failed to get hostname for connection");
446- return NULL;
447+ return 0;
448 }
449
450 nhost = strdup(host);
451 if (!nhost) {
452- unbind_ldap_connection(ldap, ctxt);
453 debug(LOGOPT_ANY, "failed to alloc context for hostname");
454- return NULL;
455+ return 0;
456 }
457 ldap_memfree(host);
458
459@@ -443,7 +455,7 @@ static LDAP *do_connect(struct lookup_context *ctxt)
460 }
461
462 if (!need_base)
463- return ldap;
464+ return 1;
465
466 /*
467 * If the schema isn't defined in the configuration then check for
468@@ -452,20 +464,134 @@ static LDAP *do_connect(struct lookup_context *ctxt)
469 */
470 if (!ctxt->schema) {
471 if (!find_query_dn(ldap, ctxt)) {
472- unbind_ldap_connection(ldap, ctxt);
473 error(LOGOPT_ANY,
474 MODPREFIX "failed to find valid query dn");
475- return NULL;
476+ return 0;
477 }
478 } else {
479 const char *class = ctxt->schema->map_class;
480 const char *key = ctxt->schema->map_attr;
481 if (!get_query_dn(ldap, ctxt, class, key)) {
482- unbind_ldap_connection(ldap, ctxt);
483 error(LOGOPT_ANY, MODPREFIX "failed to get query dn");
484+ return 0;
485+ }
486+ }
487+
488+ return 1;
489+}
490+
491+static LDAP *do_connect(const char *uri, struct lookup_context *ctxt)
492+{
493+ LDAP *ldap;
494+
495+ ldap = init_ldap_connection(uri, ctxt);
496+ if (!ldap)
497+ return NULL;
498+
499+ if (!do_bind(ldap, ctxt)) {
500+ unbind_ldap_connection(ldap, ctxt);
501+ return NULL;
502+ }
503+
504+ return ldap;
505+}
506+
507+static LDAP *connect_to_server(const char *uri, struct lookup_context *ctxt)
508+{
509+ LDAP *ldap;
510+
511+#ifdef WITH_SASL
512+ /*
513+ * Determine which authentication mechanism to use if we require
514+ * authentication.
515+ */
516+ if (ctxt->auth_required & LDAP_AUTH_REQUIRED) {
517+ ldap = auth_init(uri, ctxt);
518+ if (!ldap && ctxt->auth_required & LDAP_AUTH_AUTODETECT)
519+ warn(LOGOPT_NONE,
520+ "no authentication mechanisms auto detected.");
521+ if (!ldap) {
522+ error(LOGOPT_ANY, MODPREFIX
523+ "cannot initialize authentication setup");
524 return NULL;
525 }
526+
527+ if (!do_bind(ldap, ctxt)) {
528+ unbind_ldap_connection(ldap, ctxt);
529+ error(LOGOPT_ANY, MODPREFIX "cannot bind to server");
530+ return NULL;
531+ }
532+
533+ return ldap;
534+ }
535+#endif
536+
537+ ldap = do_connect(uri, ctxt);
538+ if (!ldap) {
539+ error(LOGOPT_ANY, MODPREFIX "cannot connect to server");
540+ return NULL;
541+ }
542+
543+ return ldap;
544+}
545+
546+static LDAP *find_server(struct lookup_context *ctxt)
547+{
548+ LDAP *ldap = NULL;
549+ struct ldap_uri *this;
550+ struct list_head *p;
551+ LIST_HEAD(tmp);
552+
553+ /* Try each uri in list, add connect fails to tmp list */
554+ p = ctxt->uri->next;
555+ while(p != ctxt->uri) {
556+ this = list_entry(p, struct ldap_uri, list);
557+ p = p->next;
558+ debug(LOGOPT_ANY, "check uri %s", this->uri);
559+ ldap = connect_to_server(this->uri, ctxt);
560+ if (ldap) {
561+ debug(LOGOPT_ANY, "connexted to uri %s", this->uri);
562+ break;
563+ }
564+ list_del_init(&this->list);
565+ list_add_tail(&this->list, &tmp);
566 }
567+ /*
568+ * Successfuly connected uri (head of list) and untried uris are
569+ * in ctxt->uri list. Make list of remainder and failed uris with
570+ * failed uris at end and assign back to ctxt-uri.
571+ */
572+ list_splice(ctxt->uri, &tmp);
573+ INIT_LIST_HEAD(ctxt->uri);
574+ list_splice(&tmp, ctxt->uri);
575+
576+ return ldap;
577+}
578+
579+static LDAP *do_reconnect(struct lookup_context *ctxt)
580+{
581+ LDAP *ldap;
582+
583+ if (ctxt->server || !ctxt->uri) {
584+ ldap = do_connect(ctxt->server, ctxt);
585+ return ldap;
586+ } else {
587+ struct ldap_uri *this;
588+ this = list_entry(ctxt->uri->next, struct ldap_uri, list);
589+ ldap = do_connect(this->uri, ctxt);
590+ if (ldap)
591+ return ldap;
592+ /* Failed to connect, put at end of list */
593+ list_del_init(&this->list);
594+ list_add_tail(&this->list, ctxt->uri);
595+ }
596+
597+ autofs_sasl_done(ctxt);
598+
599+ /* Current server failed connect, try the rest */
600+ ldap = find_server(ctxt);
601+ if (!ldap)
602+ error(LOGOPT_ANY, MODPREFIX "failed to find available server");
603
604 return ldap;
605 }
606@@ -760,10 +886,10 @@ out:
607 * information. If there is no configuration file, then we fall back to
608 * trying all supported authentication mechanisms until one works.
609 *
610- * Returns 0 on success, with authtype, user and secret filled in as
611- * appropriate. Returns -1 on failre.
612+ * Returns ldap connection on success, with authtype, user and secret
613+ * filled in as appropriate. Returns NULL on failre.
614 */
615-int auth_init(struct lookup_context *ctxt)
616+static LDAP *auth_init(const char *uri, struct lookup_context *ctxt)
617 {
618 int ret;
619 LDAP *ldap;
620@@ -776,14 +902,11 @@ int auth_init(struct lookup_context *ctxt)
621 */
622 ret = parse_ldap_config(ctxt);
623 if (ret)
624- return -1;
625-
626- if (ctxt->auth_required & LDAP_AUTH_NOTREQUIRED)
627- return 0;
628+ return NULL;
629
630- ldap = init_ldap_connection(ctxt);
631+ ldap = init_ldap_connection(uri, ctxt);
632 if (!ldap)
633- return -1;
634+ return NULL;
635
636 /*
637 * Initialize the sasl library. It is okay if user and secret
638@@ -794,18 +917,12 @@ int auth_init(struct lookup_context *ctxt)
639 * the credential cache and the client and service principals.
640 */
641 ret = autofs_sasl_init(ldap, ctxt);
642- unbind_ldap_connection(ldap, ctxt);
643 if (ret) {
644 ctxt->sasl_mech = NULL;
645- if (ctxt->auth_required & LDAP_AUTH_AUTODETECT) {
646- warn(LOGOPT_NONE,
647- "no authentication mechanisms auto detected.");
648- return 0;
649- }
650- return -1;
651+ return NULL;
652 }
653
654- return 0;
655+ return ldap;
656 }
657 #endif
658
659@@ -1036,6 +1153,8 @@ static void free_context(struct lookup_context *ctxt)
660 free(ctxt->cur_host);
661 if (ctxt->base)
662 free(ctxt->base);
663+ if (ctxt->uri)
664+ defaults_free_uris(ctxt->uri);
665 if (ctxt->sdns)
666 defaults_free_searchdns(ctxt->sdns);
667 free(ctxt);
668@@ -1043,6 +1162,30 @@ static void free_context(struct lookup_context *ctxt)
669 return;
670 }
671
672+static void validate_uris(struct list_head *list)
673+{
674+ struct list_head *next;
675+
676+ next = list->next;
677+ while (next != list) {
678+ struct ldap_uri *this;
679+
680+ this = list_entry(next, struct ldap_uri, list);
681+ next = next->next;
682+
683+ /* At least we get some basic validation */
684+ if (!ldap_is_ldap_url(this->uri)) {
685+ warn(LOGOPT_ANY,
686+ "removed invalid uri from list, %s", this->uri);
687+ list_del(&this->list);
688+ free(this->uri);
689+ free(this);
690+ }
691+ }
692+
693+ return;
694+}
695+
696 /*
697 * This initializes a context (persistent non-global data) for queries to
698 * this module. Return zero if we succeed.
699@@ -1051,7 +1194,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
700 {
701 struct lookup_context *ctxt;
702 char buf[MAX_ERR_BUF];
703- int ret;
704 LDAP *ldap = NULL;
705
706 *context = NULL;
707@@ -1079,33 +1221,42 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
708 return 1;
709 }
710
711-#ifdef WITH_SASL
712- /*
713- * Determine which authentication mechanism to use. We sanity-
714- * check by binding to the server temporarily.
715- */
716- ret = auth_init(ctxt);
717- if (ret && (ctxt->auth_required & LDAP_AUTH_REQUIRED)) {
718- error(LOGOPT_ANY, MODPREFIX
719- "cannot initialize authentication setup");
720- free_context(ctxt);
721- return 1;
722+ ctxt->timeout = defaults_get_ldap_timeout();
723+ ctxt->network_timeout = defaults_get_ldap_network_timeout();
724+
725+ if (!ctxt->server) {
726+ struct list_head *uris = defaults_get_uris();
727+ if (uris) {
728+ validate_uris(uris);
729+ if (!list_empty(uris))
730+ ctxt->uri = uris;
731+ else
732+ free(uris);
733+ }
734 }
735-#endif
736
737- ldap = do_connect(ctxt);
738- if (!ldap) {
739- error(LOGOPT_ANY, MODPREFIX "cannot connect to server");
740- free_context(ctxt);
741- return 1;
742+ if (ctxt->server || !ctxt->uri) {
743+ ldap = connect_to_server(ctxt->server, ctxt);
744+ if (!ldap) {
745+ free_context(ctxt);
746+ return 1;
747+ }
748+ } else {
749+ ldap = find_server(ctxt);
750+ if (!ldap) {
751+ free_context(ctxt);
752+ error(LOGOPT_ANY, MODPREFIX
753+ "failed to find available server");
754+ return 1;
755+ }
756 }
757 unbind_ldap_connection(ldap, ctxt);
758
759 /* Open the parser, if we can. */
760 ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
761 if (!ctxt->parse) {
762- crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
763 free_context(ctxt);
764+ crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
765 return 1;
766 }
767 *context = ctxt;
768@@ -1153,7 +1304,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
769 query[l] = '\0';
770
771 /* Initialize the LDAP context. */
772- ldap = do_connect(ctxt);
773+ ldap = do_reconnect(ctxt);
774 if (!ldap)
775 return NSS_STATUS_UNAVAIL;
776
777@@ -1305,7 +1456,7 @@ static int read_one_map(struct autofs_point *ap,
778 query[l] = '\0';
779
780 /* Initialize the LDAP context. */
781- ldap = do_connect(ctxt);
782+ ldap = do_reconnect(ctxt);
783 if (!ldap)
784 return NSS_STATUS_UNAVAIL;
785
786@@ -1536,6 +1687,9 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
787 if (ret != NSS_STATUS_SUCCESS) {
788 switch (rv) {
789 case LDAP_SIZELIMIT_EXCEEDED:
790+ crit(ap->logopt, MODPREFIX
791+ "Unable to download entire LDAP map for: %s",
792+ ap->path);
793 case LDAP_UNWILLING_TO_PERFORM:
794 pthread_setcancelstate(cur_state, NULL);
795 return NSS_STATUS_UNAVAIL;
796@@ -1612,7 +1766,7 @@ static int lookup_one(struct autofs_point *ap,
797 query[ql] = '\0';
798
799 /* Initialize the LDAP context. */
800- ldap = do_connect(ctxt);
801+ ldap = do_reconnect(ctxt);
802 if (!ldap)
803 return CHE_FAIL;
804
805diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in
806index 2b1e20a..f01ee5f 100644
807--- a/redhat/autofs.sysconfig.in
808+++ b/redhat/autofs.sysconfig.in
809@@ -23,6 +23,25 @@ BROWSE_MODE="no"
810 #
811 # Define base dn for map dn lookup.
812 #
813+# Define server URIs
814+#
815+# LDAP_URI - space seperated list of server uris of the form
816+# <proto>://<server>[/] where <proto> can be ldap
817+# or ldaps. The option can be given multiple times.
818+# Map entries that include a server name override
819+# this option.
820+#
821+#LDAP_URI=""
822+#
823+# LDAP__TIMEOUT - timeout value for the synchronous API calls
824+# (default is LDAP library default).
825+#
826+#LDAP_TIMEOUT=-1
827+#
828+# LDAP_NETWORK_TIMEOUT - set the network response timeout (default 8).
829+#
830+#LDAP_NETWORK_TIMEOUT=8
831+#
832 # SEARCH_BASE - base dn to use for searching for map search dn.
833 # Multiple entries can be given and they are checked
834 # in the order they occur here.
835diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
836index 2b1e20a..028341c 100644
837--- a/samples/autofs.conf.default.in
838+++ b/samples/autofs.conf.default.in
839@@ -21,6 +21,25 @@ BROWSE_MODE="no"
840 #
841 #LOGGING="none"
842 #
843+# Define server URIs
844+#
845+# LDAP_URI - space seperated list of server uris of the form
846+# <proto>://<server>[/] where <proto> can be ldap
847+# or ldaps. The option can be given multiple times.
848+# Map entries that include a server name override
849+# this option.
850+#
851+#LDAP_URI=""
852+#
853+# LDAP__TIMEOUT - timeout value for the synchronous API calls
854+# (default is LDAP library default).
855+#
856+#LDAP_TIMEOUT=-1
857+#
858+# LDAP_NETWORK_TIMEOUT - set the network response timeout (default 8).
859+#
860+#LDAP_NETWORK_TIMEOUT=8
861+#
862 # Define base dn for map dn lookup.
863 #
864 # SEARCH_BASE - base dn to use for searching for map search dn.
This page took 0.132651 seconds and 4 git commands to generate.