* Exim - an Internet mail transport agent *
*************************************************/
+/* Copyright (c) The Exim Maintainers 2020 - 2023 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
-/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Many thanks to Stuart Lynne for contributing the original code for this
driver. Further contributions from Michael Haardt, Brian Candler, Barry
g = string_catn(NULL, ldap_url, init_ptr - ldap_url);
g = string_fmt_append(g, "//%s:%d/", shost, port);
}
- string_from_gstring(g);
/* Call ldap_initialize() and check the result */
+ {
+ const uschar * s = string_from_gstring(g);
- DEBUG(D_lookup) debug_printf_indent("ldap_initialize with URL %s\n", g->s);
- if ((rc = ldap_initialize(&ld, CS g->s)) != LDAP_SUCCESS)
- {
- *errmsg = string_sprintf("ldap_initialize: (error %d) URL \"%s\"\n",
- rc, g->s);
- goto RETURN_ERROR;
- }
+ DEBUG(D_lookup) debug_printf_indent("ldap_initialize with URL %s\n", s);
+ if ((rc = ldap_initialize(&ld, CS s)) != LDAP_SUCCESS)
+ {
+ *errmsg = string_sprintf("ldap_initialize: (error %d) URL \"%s\"\n",
+ rc, s);
+ goto RETURN_ERROR;
+ }
+ }
store_reset(reset_point); /* Might as well save memory when we can */
/* Now add this connection to the chain of cached connections */
- lcp = store_get(sizeof(LDAP_CONNECTION), FALSE);
+ lcp = store_get(sizeof(LDAP_CONNECTION), GET_UNTAINTED);
lcp->host = host ? string_copy(host) : NULL;
lcp->bound = FALSE;
lcp->user = NULL;
uschar **errmsg)
{
BOOL defer_break = FALSE;
-int timelimit = LDAP_NO_LIMIT;
-int sizelimit = LDAP_NO_LIMIT;
+int timelimit = LDAP_NO_LIMIT, sizelimit = LDAP_NO_LIMIT;
int tcplimit = 0;
int sep = 0;
int dereference = LDAP_DEREF_NEVER;
-void* referrals = LDAP_OPT_ON;
-const uschar *url = ldap_url;
-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++;
+void * referrals = LDAP_OPT_ON;
+const uschar * url = ldap_url, * p, * list;
+uschar * user = NULL, * password = NULL, * local_servers = NULL;
+
+Uskip_whitespace(&url);
/* Until the string begins "ldap", search for the other parameter settings that
are recognized. They are of the form NAME=VALUE, with the value being
DEBUG(D_lookup) debug_printf_indent("LDAP query error: %s\n", *errmsg);
return DEFER;
}
- while (isspace(*url)) url++;
+ Uskip_whitespace(&url);
continue;
}
}
&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)
{
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));
}
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));
}
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));
}
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));
}
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);
}
}
s the string to be quoted
opt additional option text or NULL if none
only "dn" is recognized
+ idx lookup type index
Returns: the processed string or NULL for a bad option
*/
static uschar *
-eldap_quote(uschar *s, uschar *opt)
+eldap_quote(uschar * s, uschar * opt, unsigned idx)
{
-register int c;
-int count = 0;
-int len = 0;
+int c, count = 0, len = 0;
BOOL dn = FALSE;
-uschar *t = s;
-uschar *quoted;
+uschar * t = s, * quoted;
/* Test for a DN quotation. */
-if (opt != NULL)
+if (opt)
{
if (Ustrcmp(opt, "dn") != 0) return NULL; /* No others recognized */
dn = TRUE;
possibly escaped character. The really fast way would be just to test for
non-alphanumerics, but it is probably better to spot a few others that are
never escaped, because if there are no specials at all, we can avoid copying
-the string. */
+the string.
+XXX No longer true; we always copy, to support quoted-enforcement */
-while ((c = *t++) != 0)
+while ((c = *t++))
{
len++;
if (!isalnum(c) && Ustrchr(ALWAYS_LITERAL, c) == NULL) count += 5;
}
-if (count == 0) return s;
+/*if (count == 0) return s;*/
/* Get sufficient store to hold the quoted string */
-t = quoted = store_get(len + count + 1, is_tainted(s));
+t = quoted = store_get_quoted(len + count + 1, s, idx);
/* Handle plain quote_ldap */
if (!dn)
{
- while ((c = *s++) != 0)
+ while ((c = *s++))
{
if (!isalnum(c))
{
else
{
- uschar *ss = s + len;
+ uschar * ss = s + len;
/* Find the last char before any trailing spaces */
{
if (Ustrchr(LDAP_DN_QUOTE, c) != NULL)
{
- Ustrncpy(t, US"%5C", 3); /* insert \ where needed */
- t += 3; /* fall through to check URL */
+ memcpy(t, US"%5C", 3); /* insert \ where needed */
+ t += 3; /* fall through to check URL */
}
if (Ustrchr(URL_NONQUOTE, c) == NULL) /* e.g. ] => %5D */
{
/* Handle the trailing spaces */
- while (*ss++ != 0)
+ while (*ss++)
{
- Ustrncpy(t, US"%5C%20", 6);
+ memcpy(t, US"%5C%20", 6);
t += 6;
}
}
#include "../version.h"
-void
-ldap_version_report(FILE *f)
+gstring *
+ldap_version_report(gstring * g)
{
#ifdef DYNLOOKUP
-fprintf(f, "Library version: LDAP: Exim version %s\n", EXIM_VERSION_STR);
+g = string_fmt_append(g, "Library version: LDAP: Exim version %s\n", EXIM_VERSION_STR);
#endif
+return g;
}