]> git.pld-linux.org Git - packages/autofs.git/blob - autofs-5.0.2-add-multiple-server-selection-option.patch
ef9b3f97a3bf3ce9a902e070c90e83a8ac6d96b7
[packages/autofs.git] / autofs-5.0.2-add-multiple-server-selection-option.patch
1 diff --git a/CHANGELOG b/CHANGELOG
2 index 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  -----------------------
13 diff --git a/include/defaults.h b/include/defaults.h
14 index 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);
38 diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
39 index 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  
91 diff --git a/lib/defaults.c b/lib/defaults.c
92 index 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)
265 diff --git a/man/auto.master.5.in b/man/auto.master.5.in
266 index 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
298 diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
299 index 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  
805 diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in
806 index 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.
835 diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
836 index 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.530006 seconds and 2 git commands to generate.