Skip to content

Commit b764080

Browse files
committed
Fix timeout in LDAP lookup of libpq connection parameters
Bind attempts to an LDAP server should time out after two seconds, allowing additional lines in the service control file to be parsed (which provide a fall back to a secondary LDAP server or default options). The existing code failed to enforce that timeout during TCP connect, resulting in a hang far longer than two seconds if the LDAP server does not respond. Laurenz Albe
1 parent 966f015 commit b764080

File tree

1 file changed

+39
-7
lines changed

1 file changed

+39
-7
lines changed

src/interfaces/libpq/fe-connect.c

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3563,12 +3563,37 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
35633563
}
35643564

35653565
/*
3566-
* Initialize connection to the server. We do an explicit bind because we
3567-
* want to return 2 if the bind fails.
3566+
* Perform an explicit anonymous bind.
3567+
* LDAP does not require that an anonymous bind is preformed explicitly,
3568+
* but we want to distinguish between the case where LDAP bind does not
3569+
* succeed within PGLDAP_TIMEOUT seconds (return 2 to continue parsing
3570+
* the service control file) and the case where querying the LDAP server
3571+
* fails (return 1 to end parsing).
3572+
* Unfortunately there is no way of setting a timeout that works for
3573+
* both Windows and OpenLDAP.
35683574
*/
3575+
#ifdef WIN32
3576+
/* the nonstandard ldap_connect function performs an anonymous bind */
3577+
if (ldap_connect(ld, &time) != LDAP_SUCCESS)
3578+
{
3579+
/* error or timeout in ldap_connect */
3580+
free(url);
3581+
ldap_unbind(ld);
3582+
return 2;
3583+
}
3584+
#else /* WIN32 */
3585+
/* in OpenLDAP, use the LDAP_OPT_NETWORK_TIMEOUT option */
3586+
if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
3587+
{
3588+
free(url);
3589+
ldap_unbind(ld);
3590+
return 3;
3591+
}
3592+
3593+
/* anonymous bind */
35693594
if ((msgid = ldap_simple_bind(ld, NULL, NULL)) == -1)
35703595
{
3571-
/* error in ldap_simple_bind() */
3596+
/* error or network timeout */
35723597
free(url);
35733598
ldap_unbind(ld);
35743599
return 2;
@@ -3579,18 +3604,25 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
35793604
if ((rc = ldap_result(ld, msgid, LDAP_MSG_ALL, &time, &res)) == -1 ||
35803605
res == NULL)
35813606
{
3607+
/* error or timeout */
35823608
if (res != NULL)
3583-
{
3584-
/* timeout */
35853609
ldap_msgfree(res);
3586-
}
3587-
/* error in ldap_result() */
35883610
free(url);
35893611
ldap_unbind(ld);
35903612
return 2;
35913613
}
35923614
ldap_msgfree(res);
35933615

3616+
/* reset timeout */
3617+
time.tv_sec = -1;
3618+
if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
3619+
{
3620+
free(url);
3621+
ldap_unbind(ld);
3622+
return 3;
3623+
}
3624+
#endif /* WIN32 */
3625+
35943626
/* search */
35953627
res = NULL;
35963628
if ((rc = ldap_search_st(ld, dn, scope, filter, attrs, 0, &time, &res))

0 commit comments

Comments
 (0)