struct timeval timeout;
struct timeval *timeoutptr = NULL;
-uschar *attr;
-uschar **attrp;
gstring * data = NULL;
uschar *dn = NULL;
uschar *host;
BOOL attribute_found = FALSE;
BOOL ldapi = FALSE;
-DEBUG(D_lookup)
- debug_printf("perform_ldap_search: ldap%s URL = \"%s\" server=%s port=%d "
+DEBUG(D_lookup) debug_printf_indent("perform_ldap_search:"
+ " ldap%s URL = \"%s\" server=%s port=%d "
"sizelimit=%d timelimit=%d tcplimit=%d\n",
search_type == SEARCH_LDAP_MULTIPLE ? "m" :
search_type == SEARCH_LDAP_DN ? "dn" :
port = ludp->lud_port;
}
-DEBUG(D_lookup) debug_printf("after ldap_url_parse: host=%s port=%d\n",
+DEBUG(D_lookup) debug_printf_indent("after ldap_url_parse: host=%s port=%d\n",
host, port);
if (port == 0) port = LDAP_PORT; /* Default if none given */
/* Count the attributes; we need this later to tell us how to format results */
-for (attrp = USS ludp->lud_attrs; attrp && *attrp; attrp++)
+for (uschar ** attrp = USS ludp->lud_attrs; attrp && *attrp; attrp++)
attrs_requested++;
/* See if we can find a cached connection to this host. The port is not
than the host name + "ldaps:///" plus : and a port number, say 20 + the
length of the host name. What we get should accommodate both, easily. */
- uschar *shost = (host == NULL)? US"" : host;
- uschar *init_url = store_get(20 + 3 * Ustrlen(shost));
- uschar *init_ptr;
+ uschar * shost = host ? host : US"";
+ rmark reset_point = store_mark();
+ gstring * g;
/* Handle connection via Unix socket ("ldapi"). We build a basic LDAP URI to
contain the path name, with slashes escaped as %2F. */
if (ldapi)
{
- int ch;
- init_ptr = init_url + 8;
- Ustrcpy(init_url, "ldapi://");
- while ((ch = *shost++))
- if (ch == '/')
- { Ustrncpy(init_ptr, "%2F", 3); init_ptr += 3; }
- else
- *init_ptr++ = ch;
- *init_ptr = 0;
+ g = string_catn(NULL, US"ldapi://", 8);
+ for (uschar ch; (ch = *shost); shost++)
+ g = ch == '/' ? string_catn(g, US"%2F", 3) : string_catn(g, shost, 1);
}
/* This is not an ldapi call. Just build a URI with the protocol type, host
else
{
- init_ptr = Ustrchr(ldap_url, '/');
- Ustrncpy(init_url, ldap_url, init_ptr - ldap_url);
- init_ptr = init_url + (init_ptr - ldap_url);
- sprintf(CS init_ptr, "//%s:%d/", shost, port);
+ uschar * init_ptr = Ustrchr(ldap_url, '/');
+ 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 */
- DEBUG(D_lookup) debug_printf("ldap_initialize with URL %s\n", init_url);
- if ((rc = ldap_initialize(&ld, CS init_url)) != LDAP_SUCCESS)
+ 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, init_url);
+ rc, g->s);
goto RETURN_ERROR;
}
- store_reset(init_url); /* Might as well save memory when we can */
+ store_reset(reset_point); /* Might as well save memory when we can */
/* ------------------------- Not OpenLDAP ---------------------- */
ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, (void *)&eldap_version);
#endif
- DEBUG(D_lookup) debug_printf("initialized for LDAP (v%d) server %s%s\n",
+ DEBUG(D_lookup) debug_printf_indent("initialized for LDAP (v%d) server %s%s\n",
eldap_version, host, porttext);
/* If not using ldapi and TLS is available, set appropriate TLS options: hard
: Ustrcmp(eldap_require_cert, "try") == 0 ? LDAP_OPT_X_TLS_TRY
: LDAP_OPT_X_TLS_NEVER;
- DEBUG(D_lookup)
- debug_printf("Require certificate overrides LDAP_OPT_X_TLS option (%d)\n",
- tls_option);
+ DEBUG(D_lookup) debug_printf_indent(
+ "Require certificate overrides LDAP_OPT_X_TLS option (%d)\n",
+ tls_option);
}
else
# endif /* LDAP_OPT_X_TLS_REQUIRE_CERT */
{
tls_option = LDAP_OPT_X_TLS_HARD;
DEBUG(D_lookup)
- debug_printf("LDAP_OPT_X_TLS_HARD set due to ldaps:// URI\n");
+ debug_printf_indent("LDAP_OPT_X_TLS_HARD set due to ldaps:// URI\n");
}
else
{
tls_option = LDAP_OPT_X_TLS_TRY;
DEBUG(D_lookup)
- debug_printf("LDAP_OPT_X_TLS_TRY set due to ldap:// URI\n");
+ debug_printf_indent("LDAP_OPT_X_TLS_TRY set due to ldap:// URI\n");
}
ldap_set_option(ld, LDAP_OPT_X_TLS, (void *)&tls_option);
}
rc = ldap_set_option(ldsetctx, LDAP_OPT_X_TLS_REQUIRE_CERT, &cert_option);
if (rc)
DEBUG(D_lookup)
- debug_printf("Unable to set TLS require cert_option(%d) globally: %s\n",
+ debug_printf_indent("Unable to set TLS require cert_option(%d) globally: %s\n",
cert_option, ldap_err2string(rc));
}
#endif
#ifdef LDAP_OPT_X_TLS_NEWCTX
if ((rc = ldap_set_option(ldsetctx, LDAP_OPT_X_TLS_NEWCTX, &am_server)))
DEBUG(D_lookup)
- debug_printf("Unable to reload TLS context %d: %s\n",
+ debug_printf_indent("Unable to reload TLS context %d: %s\n",
rc, ldap_err2string(rc));
#endif
/* Now add this connection to the chain of cached connections */
- lcp = store_get(sizeof(LDAP_CONNECTION));
- lcp->host = (host == NULL)? NULL : string_copy(host);
+ lcp = store_get(sizeof(LDAP_CONNECTION), FALSE);
+ lcp->host = host ? string_copy(host) : NULL;
lcp->bound = FALSE;
lcp->user = NULL;
lcp->password = NULL;
else
DEBUG(D_lookup)
- debug_printf("re-using cached connection to LDAP server %s%s\n",
+ debug_printf_indent("re-using cached connection to LDAP server %s%s\n",
host, porttext);
/* Bind with the user/password supplied, or an anonymous bind if these values
|| lcp->password && password && Ustrcmp(lcp->password, password) != 0
)
{
- DEBUG(D_lookup) debug_printf("%sbinding with user=%s password=%s\n",
+ DEBUG(D_lookup) debug_printf_indent("%sbinding with user=%s password=%s\n",
lcp->bound ? "re-" : "", user, password);
if (eldap_start_tls && !lcp->is_start_tls_called && !ldapi)
}
lcp->is_start_tls_called = TRUE;
#else
- DEBUG(D_lookup) debug_printf("TLS initiation not supported with this Exim"
+ DEBUG(D_lookup) debug_printf_indent("TLS initiation not supported with this Exim"
" and your LDAP library.\n");
#endif
}
if (search_type == SEARCH_LDAP_AUTH && rc == LDAP_INVALID_CREDENTIALS)
{
DEBUG(D_lookup)
- debug_printf("Invalid credentials: ldapauth returns FAIL\n");
+ debug_printf_indent("Invalid credentials: ldapauth returns FAIL\n");
error_yield = FAIL;
goto RETURN_ERROR_NOMSG;
}
if (search_type == SEARCH_LDAP_AUTH)
{
- DEBUG(D_lookup) debug_printf("Bind succeeded: ldapauth returns OK\n");
+ DEBUG(D_lookup) debug_printf_indent("Bind succeeded: ldapauth returns OK\n");
goto RETURN_OK;
}
/* Start the search on the server. */
-DEBUG(D_lookup) debug_printf("Start search\n");
+DEBUG(D_lookup) debug_printf_indent("Start search\n");
msgid = ldap_search(lcp->ld, ludp->lud_dn, ludp->lud_scope, ludp->lud_filter,
ludp->lud_attrs, 0);
then we get two entries, one for A and one for B.
Here we just count the values per entry */
- DEBUG(D_lookup) debug_printf("LDAP result loop\n");
+ DEBUG(D_lookup) debug_printf_indent("LDAP result loop\n");
for(e = ldap_first_entry(lcp->ld, result), valuecount = 0;
e;
uschar *new_dn;
BOOL insert_space = FALSE;
- DEBUG(D_lookup) debug_printf("LDAP entry loop\n");
+ DEBUG(D_lookup) debug_printf_indent("LDAP entry loop\n");
rescount++; /* Count results */
sequence of name=value pairs, separated by (space), with the value always in quotes.
If there are multiple values, they are given within the quotes, comma separated. */
- else for (attr = US ldap_first_attribute(lcp->ld, e, &ber);
+ else for (uschar * attr = US ldap_first_attribute(lcp->ld, e, &ber);
attr; attr = US ldap_next_attribute(lcp->ld, e, ber))
{
- DEBUG(D_lookup) debug_printf("LDAP attr loop\n");
+ DEBUG(D_lookup) debug_printf_indent("LDAP attr loop\n");
/* In case of attrs_requested == 1 we just count the values, in all other cases
(0, >1) we count the values per attribute */
int len = Ustrlen(value);
++valuecount;
- DEBUG(D_lookup) debug_printf("LDAP value loop %s:%s\n", attr, value);
+ DEBUG(D_lookup) debug_printf_indent("LDAP value loop %s:%s\n", attr, value);
/* In case we requested one attribute only but got several times
into that attr loop, we need to append the additional values.
internal quotes, backslashes, newlines, and must double commas. */
if (attrs_requested != 1)
- {
- int j;
- for (j = 0; j < len; j++)
+ for (int j = 0; j < len; j++)
{
if (value[j] == '\n')
data = string_catn(data, US"\\n", 2);
data = string_catn(data, value+j, 1);
}
}
- }
/* For single attributes, just double commas */
else
- {
- int j;
- for (j = 0; j < len; j++)
+ for (int j = 0; j < len; j++)
if (value[j] == ',')
data = string_catn(data, US",,", 2);
else
data = string_catn(data, value+j, 1);
- }
/* Move on to the next value */
if (!data) data = string_get(1);
(void) string_from_gstring(data);
-gstring_reset_unused(data);
+gstring_release_unused(data);
/* Copy the last dn into eldap_dn */
#endif
}
-DEBUG(D_lookup) debug_printf("search ended by ldap_result yielding %d\n",rc);
+DEBUG(D_lookup) debug_printf_indent("search ended by ldap_result yielding %d\n",rc);
if (rc == 0)
{
if (rc == -1 || !result)
{
int err;
- DEBUG(D_lookup) debug_printf("ldap_result failed\n");
+ DEBUG(D_lookup) debug_printf_indent("ldap_result failed\n");
#if defined LDAP_LIB_SOLARIS || defined LDAP_LIB_OPENLDAP2
ldap_get_option(lcp->ld, LDAP_OPT_ERROR_NUMBER, &err);
ldap_rc = rc;
ldap_parse_rc = ldap_parse_result(lcp->ld, result, &rc, CSS &matched,
CSS &error2, NULL, NULL, 0);
- DEBUG(D_lookup) debug_printf("ldap_parse_result: %d\n", ldap_parse_rc);
+ DEBUG(D_lookup) debug_printf_indent("ldap_parse_result: %d\n", ldap_parse_rc);
if (ldap_parse_rc < 0 &&
(ldap_parse_rc != LDAP_NO_RESULTS_RETURNED
#ifdef LDAP_RES_SEARCH_REFERENCE
the lookup, so return DEFER (which is the default in error_yield).
*/
-DEBUG(D_lookup) debug_printf("ldap_parse_result yielded %d: %s\n",
+DEBUG(D_lookup) debug_printf_indent("ldap_parse_result yielded %d: %s\n",
rc, ldap_err2string(rc));
if (rc != LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED
#endif
{
- DEBUG(D_lookup) debug_printf("lookup failure forced\n");
+ DEBUG(D_lookup) debug_printf_indent("lookup failure forced\n");
error_yield = FAIL;
}
goto RETURN_ERROR;
if (rescount < 1)
{
- *errmsg = string_sprintf("LDAP search: no results");
+ *errmsg = US"LDAP search: no results";
error_yield = FAIL;
goto RETURN_ERROR_BREAK;
}
/* Otherwise, it's all worked */
-DEBUG(D_lookup) debug_printf("LDAP search: returning: %s\n", data->s);
+DEBUG(D_lookup) debug_printf_indent("LDAP search: returning: %s\n", data->s);
*res = data->s;
RETURN_OK:
*defer_break = TRUE;
RETURN_ERROR:
-DEBUG(D_lookup) debug_printf("%s\n", *errmsg);
+DEBUG(D_lookup) debug_printf_indent("%s\n", *errmsg);
RETURN_ERROR_NOMSG:
if (result) ldap_msgfree(result);
{
*errmsg = string_sprintf("LDAP_OP_DEREF not defined in this LDAP "
"library - cannot use \"dereference\"");
- DEBUG(D_lookup) debug_printf("%s\n", *errmsg);
+ DEBUG(D_lookup) debug_printf_indent("%s\n", *errmsg);
return DEFER;
}
#endif
else if (strcmpic(value, US"nofollow") == 0) referrals = LDAP_OPT_OFF;
else
{
- *errmsg = string_sprintf("LDAP option REFERRALS is not \"follow\" "
- "or \"nofollow\"");
- DEBUG(D_lookup) debug_printf("%s\n", *errmsg);
+ *errmsg = US"LDAP option REFERRALS is not \"follow\" or \"nofollow\"";
+ DEBUG(D_lookup) debug_printf_indent("%s\n", *errmsg);
return DEFER;
}
}
{
*errmsg = string_sprintf("LDAP_OP_REFERRALS not defined in this LDAP "
"library - cannot use \"referrals\"");
- DEBUG(D_lookup) debug_printf("%s\n", *errmsg);
+ DEBUG(D_lookup) debug_printf_indent("%s\n", *errmsg);
return DEFER;
}
#endif
*errmsg =
string_sprintf("unknown parameter \"%.*s\" precedes LDAP URL",
namelen, name);
- DEBUG(D_lookup) debug_printf("LDAP query error: %s\n", *errmsg);
+ DEBUG(D_lookup) debug_printf_indent("LDAP query error: %s\n", *errmsg);
return DEFER;
}
while (isspace(*url)) url++;
}
}
*errmsg = US"malformed parameter setting precedes LDAP URL";
- DEBUG(D_lookup) debug_printf("LDAP query error: %s\n", *errmsg);
+ DEBUG(D_lookup) debug_printf_indent("LDAP query error: %s\n", *errmsg);
return DEFER;
}
if (user != NULL)
{
- uschar *s;
uschar *t = user;
- for (s = user; *s != 0; s++)
+ for (uschar * s = user; *s != 0; s++)
{
int c, d;
if (*s == '%' && isxdigit(c=s[1]) && isxdigit(d=s[2]))
}
DEBUG(D_lookup)
- debug_printf("LDAP parameters: user=%s pass=%s size=%d time=%d connect=%d "
+ debug_printf_indent("LDAP parameters: user=%s pass=%s size=%d time=%d connect=%d "
"dereference=%d referrals=%s\n", user, password, sizelimit, timelimit,
tcplimit, dereference, (referrals == LDAP_OPT_ON)? "on" : "off");
}
if (password[0] == 0)
{
- DEBUG(D_lookup) debug_printf("Empty password: ldapauth returns FAIL\n");
+ DEBUG(D_lookup) debug_printf_indent("Empty password: ldapauth returns FAIL\n");
return FAIL;
}
}
{
*errmsg = string_sprintf("LDAP URL does not start with \"ldap://\", "
"\"ldaps://\", or \"ldapi://\" (it starts with \"%.16s...\")", url);
- DEBUG(D_lookup) debug_printf("LDAP query error: %s\n", *errmsg);
+ DEBUG(D_lookup) debug_printf_indent("LDAP query error: %s\n", *errmsg);
return DEFER;
}
while ((lcp = ldap_connections) != NULL)
{
- DEBUG(D_lookup) debug_printf("unbind LDAP connection to %s:%d\n", lcp->host,
+ 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);
/* Get sufficient store to hold the quoted string */
-t = quoted = store_get(len + count + 1);
+t = quoted = store_get(len + count + 1, is_tainted(s));
/* Handle plain quote_ldap */
{
if (Ustrchr(LDAP_DN_QUOTE, c) != NULL)
{
- Ustrncpy(t, "%5C", 3); /* insert \ where needed */
+ Ustrncpy(t, US"%5C", 3); /* insert \ where needed */
t += 3; /* fall through to check URL */
}
if (Ustrchr(URL_NONQUOTE, c) == NULL) /* e.g. ] => %5D */
while (*ss++ != 0)
{
- Ustrncpy(t, "%5C%20", 6);
+ Ustrncpy(t, US"%5C%20", 6);
t += 6;
}
}