LDAP: fix taint-check in server list walk. Bug 2646
[exim.git] / src / src / lookups / ldap.c
index aa4f3f80a036e480e7ed531922d6f594baefcf92..1674c9f1f9c716dfb19ab87f821997becf9ea908 100644 (file)
@@ -3,6 +3,7 @@
 *************************************************/
 
 /* Copyright (c) University of Cambridge 1995 - 2018 */
+/* Copyright (c) The Exim Maintainers 2020 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Many thanks to Stuart Lynne for contributing the original code for this
@@ -1090,9 +1091,7 @@ const uschar *p;
 uschar *user = NULL;
 uschar *password = NULL;
 uschar *local_servers = NULL;
-uschar *server;
 const uschar *list;
-uschar buffer[512];
 
 while (isspace(*url)) url++;
 
@@ -1250,13 +1249,13 @@ if (!eldap_default_servers && !local_servers  || p[3] != '/')
     &defer_break, user, password, sizelimit, timelimit, tcplimit, dereference,
     referrals);
 
-/* Loop through the default servers until OK or FAIL. Use local_servers list
- * if defined in the lookup, otherwise use the global default list */
-list = !local_servers ? eldap_default_servers : local_servers;
-while ((server = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
+/* Loop through the servers until OK or FAIL. Use local_servers list
+if defined in the lookup, otherwise use the global default list */
+
+list = local_servers ? local_servers : eldap_default_servers;
+for (uschar * server; server = string_nextinlist(&list, &sep, NULL, 0); )
   {
-  int rc;
-  int port = 0;
+  int rc, port = 0;
   uschar *colon = Ustrchr(server, ':');
   if (colon)
     {
@@ -1287,8 +1286,6 @@ eldap_find(void * handle, const uschar * filename, const uschar * ldap_url,
   int length, uschar ** result, uschar ** errmsg, uint * do_cache,
   const uschar * opts)
 {
-/* Keep picky compilers happy */
-do_cache = do_cache;
 return(control_ldap_search(ldap_url, SEARCH_LDAP_SINGLE, result, errmsg));
 }
 
@@ -1297,8 +1294,6 @@ eldapm_find(void * handle, const uschar * filename, const uschar * ldap_url,
   int length, uschar ** result, uschar ** errmsg, uint * do_cache,
   const uschar * opts)
 {
-/* Keep picky compilers happy */
-do_cache = do_cache;
 return(control_ldap_search(ldap_url, SEARCH_LDAP_MULTIPLE, result, errmsg));
 }
 
@@ -1307,8 +1302,6 @@ eldapdn_find(void * handle, const uschar * filename, const uschar * ldap_url,
   int length, uschar ** result, uschar ** errmsg, uint * do_cache,
   const uschar * opts)
 {
-/* Keep picky compilers happy */
-do_cache = do_cache;
 return(control_ldap_search(ldap_url, SEARCH_LDAP_DN, result, errmsg));
 }
 
@@ -1316,8 +1309,6 @@ int
 eldapauth_find(void * handle, const uschar * filename, const uschar * ldap_url,
   int length, uschar ** result, uschar ** errmsg, uint * do_cache)
 {
-/* Keep picky compilers happy */
-do_cache = do_cache;
 return(control_ldap_search(ldap_url, SEARCH_LDAP_AUTH, result, errmsg));
 }
 
@@ -1347,16 +1338,13 @@ Make sure that eldap_dn does not refer to reclaimed or worse, freed store */
 static void
 eldap_tidy(void)
 {
-LDAP_CONNECTION *lcp = NULL;
 eldap_dn = NULL;
 
-while ((lcp = ldap_connections) != NULL)
+for (LDAP_CONNECTION *lcp; lcp = ldap_connections; ldap_connections = lcp->next)
   {
-  DEBUG(D_lookup) debug_printf_indent("unbind LDAP connection to %s:%d\n", lcp->host,
-    lcp->port);
-  if(lcp->bound == TRUE)
-    ldap_unbind(lcp->ld);
-  ldap_connections = lcp->next;
+  DEBUG(D_lookup) debug_printf_indent("unbind LDAP connection to %s:%d\n",
+    lcp->host, lcp->port);
+  if(lcp->bound) ldap_unbind(lcp->ld);
   }
 }
 
@@ -1580,39 +1568,39 @@ fprintf(f, "Library version: LDAP: Exim version %s\n", EXIM_VERSION_STR);
 
 
 static lookup_info ldap_lookup_info = {
-  US"ldap",                      /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-  eldap_open,                    /* open function */
-  NULL,                          /* check function */
-  eldap_find,                    /* find function */
-  NULL,                          /* no close function */
-  eldap_tidy,                    /* tidy function */
-  eldap_quote,                   /* quoting function */
-  ldap_version_report            /* version reporting */
+  .name = US"ldap",                    /* lookup name */
+  .type = lookup_querystyle,           /* query-style lookup */
+  .open = eldap_open,                  /* open function */
+  .check = NULL,                       /* check function */
+  .find = eldap_find,                  /* find function */
+  .close = NULL,                       /* no close function */
+  .tidy = eldap_tidy,                  /* tidy function */
+  .quote = eldap_quote,                        /* quoting function */
+  .version_report = ldap_version_report            /* version reporting */
 };
 
 static lookup_info ldapdn_lookup_info = {
-  US"ldapdn",                     /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-  eldap_open,       /* sic */    /* open function */
-  NULL,                          /* check function */
-  eldapdn_find,                  /* find function */
-  NULL,                          /* no close function */
-  eldap_tidy,       /* sic */    /* tidy function */
-  eldap_quote,      /* sic */    /* quoting function */
-  NULL                           /* no version reporting (redundant) */
+  .name = US"ldapdn",                  /* lookup name */
+  .type = lookup_querystyle,           /* query-style lookup */
+  .open = eldap_open,                  /* sic */    /* open function */
+  .check = NULL,                       /* check function */
+  .find = eldapdn_find,                        /* find function */
+  .close = NULL,                       /* no close function */
+  .tidy = eldap_tidy,                  /* sic */    /* tidy function */
+  .quote = eldap_quote,                        /* sic */    /* quoting function */
+  .version_report = NULL                           /* no version reporting (redundant) */
 };
 
 static lookup_info ldapm_lookup_info = {
-  US"ldapm",                     /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-  eldap_open,       /* sic */    /* open function */
-  NULL,                          /* check function */
-  eldapm_find,                   /* find function */
-  NULL,                          /* no close function */
-  eldap_tidy,       /* sic */    /* tidy function */
-  eldap_quote,      /* sic */    /* quoting function */
-  NULL                           /* no version reporting (redundant) */
+  .name = US"ldapm",                   /* lookup name */
+  .type = lookup_querystyle,           /* query-style lookup */
+  .open = eldap_open,                  /* sic */    /* open function */
+  .check = NULL,                       /* check function */
+  .find = eldapm_find,                 /* find function */
+  .close = NULL,                       /* no close function */
+  .tidy = eldap_tidy,                  /* sic */    /* tidy function */
+  .quote = eldap_quote,                        /* sic */    /* quoting function */
+  .version_report = NULL                           /* no version reporting (redundant) */
 };
 
 #ifdef DYNLOOKUP