Visitar URL original
ldap: connect to the address libcurl already resolved, not the hostname by vszakats · Pull Request #23304 · curl/curl · GitHub
Skip to content

ldap: connect to the address libcurl already resolved, not the hostname - #23304

Open
vszakats wants to merge 1 commit into
curl:masterfrom
vszakats:ldap-legacy-fix-cleartext-dub-resolve
Open

vszakats wants to merge 1 commit into
curl:masterfrom
vszakats:ldap-legacy-fix-cleartext-dub-resolve

Conversation

@vszakats

@vszakats vszakats commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

The legacy LDAP backend called Curl_conn_get_ip_info() to learn the
destination libcurl's connection layer had selected, but only used
ipquad.remote_port from it. ldap_init()/ldap_sslinit() were still called
with conn->origin->hostname, so the native LDAP SDK resolved and
connected to that hostname entirely on its own, independently of any
cfilter, CURLOPT_RESOLVE, or CURLOPT_CONNECT_TO decision. An application
pinning an LDAP hostname via CURLOPT_RESOLVE for SSRF protection got
that pin silently ignored.

For plain-text ldap:// connections, pass the already-resolved address
(ipquad.remote_ip) instead of the hostname, so the SDK connects to
exactly what libcurl decided. Empirically verified against a local slapd
(OpenLDAP 2.7.1): a CURLOPT_RESOLVE-pinned hostname that cannot be
resolved by the system resolver at all now still connects and completes
a search, whereas before the fix the SDK's independent re-resolution of
that hostname failed outright.

ldaps:// connections keep using the hostname: the legacy backend hands
ldaps:// TLS entirely to the native LDAP SDK (see the existing
CURLOPT_CAINFO/CURLOPT_SSL_VERIFYPEER/CURLOPT_PINNEDPUBLICKEY/
CURLOPT_SSL_VERIFYSTATUS notes for this same backend), and the SDK
verifies the server certificate against whatever host string it was
given, so switching to an IP literal there would break certificate
verification instead of just fixing destination selection. Documented as
a caveat on CURLOPT_RESOLVE and CURLOPT_CONNECT_TO instead.

Reported-by: Joshua Rogers


The legacy LDAP backend called Curl_conn_get_ip_info() to learn the
destination libcurl's connection layer had selected, but only used
ipquad.remote_port from it. ldap_init()/ldap_sslinit() were still called
with conn->origin->hostname, so the native LDAP SDK resolved and
connected to that hostname entirely on its own, independently of any
cfilter, CURLOPT_RESOLVE, or CURLOPT_CONNECT_TO decision. An application
pinning an LDAP hostname via CURLOPT_RESOLVE for SSRF protection got
that pin silently ignored.

For plain-text ldap:// connections, pass the already-resolved address
(ipquad.remote_ip) instead of the hostname, so the SDK connects to
exactly what libcurl decided. Empirically verified against a local slapd
(OpenLDAP 2.7.1): a CURLOPT_RESOLVE-pinned hostname that cannot be
resolved by the system resolver at all now still connects and completes
a search, whereas before the fix the SDK's independent re-resolution of
that hostname failed outright.

ldaps:// connections keep using the hostname: the legacy backend hands
ldaps:// TLS entirely to the native LDAP SDK (see the existing
CURLOPT_CAINFO/CURLOPT_SSL_VERIFYPEER/CURLOPT_PINNEDPUBLICKEY/
CURLOPT_SSL_VERIFYSTATUS notes for this same backend), and the SDK
verifies the server certificate against whatever host string it was
given, so switching to an IP literal there would break certificate
verification instead of just fixing destination selection. Documented as
a caveat on CURLOPT_RESOLVE and CURLOPT_CONNECT_TO instead.

Reported-by: Joshua Rogers

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Proxy tunnels can redirect LDAP SDK connections and credentials to the proxy endpoint, and the CONNECT_TO documentation misstates port behavior.

2 open findings
What changed in this PR

Updates legacy LDAP routing so plaintext connections use libcurl’s resolved address while retaining hostnames for LDAPS certificate verification.

Changes:

  • Uses the selected IP for plaintext LDAP.
  • Documents legacy LDAPS limitations.
File Description
lib/​ldap.c Selects the SDK connection host by TLS mode.
docs/​libcurl/​opts/​CURLOPT_RESOLVE.md Documents legacy LDAPS behavior.
docs/​libcurl/​opts/​CURLOPT_CONNECT_TO.md Documents LDAP connection-routing behavior.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread lib/ldap.c
Comment on lines +378 to +379
host = curlx_convert_UTF8_to_tchar(ldap_ssl ? conn->origin->hostname :
ipquad.remote_ip);
Comment on lines +82 to +88
This option has no effect on ldaps:// requests when libcurl uses the legacy
LDAP backend. That backend hands the connection to the native LDAP SDK,
which independently resolves and connects to the original hostname for its
TLS handshake. Plain-text ldap:// requests connect to the address this
option selects. When libcurl is built with USE_OPENLDAP, the OpenLDAP
backend routes the connection through curl's connection layer and this
option is honored for both schemes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good god, LLMs dueling, I feel like I'd rather close this right away.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

4 participants