From 859ce48de12986f5bf846c2800dacab893ff12c1 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Thu, 4 Dec 2025 15:32:44 +0100 Subject: [PATCH] ldap: detect version of "legacy" LDAP Legacy LDAP means an OpenLDAP-compatible implementation without the private API `ldap_init_fd()` introduced in OpenLDAP 2.4.6+ (2007-10-31), and not WinLDAP. One known example is Apple's LDAP build, which is based on OpenLDAP 2.4.28 (2011-11-25), without providing this private API. The version query API was introduced around 1998-1999, before the minimum (2.0 2000-08-01) required by curl. Follow-up to 3e2a946926853608d67805bd9f4a58345fff364a #19808 Closes #19832 --- lib/ldap.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/ldap.c b/lib/ldap.c index 6104ff2073..92cfa3967f 100644 --- a/lib/ldap.c +++ b/lib/ldap.c @@ -1029,7 +1029,27 @@ void Curl_ldap_version(char *buf, size_t bufsz) #ifdef USE_WIN32_LDAP curl_msnprintf(buf, bufsz, "WinLDAP"); #else - curl_msnprintf(buf, bufsz, "LDAP/1"); +#ifdef __APPLE__ + static const char *flavor = "/Apple"; +#else + static const char *flavor = ""; +#endif + LDAPAPIInfo api; + api.ldapai_info_version = LDAP_API_INFO_VERSION; + + if(ldap_get_option(NULL, LDAP_OPT_API_INFO, &api) == LDAP_OPT_SUCCESS) { + unsigned int patch = (unsigned int)(api.ldapai_vendor_version % 100); + unsigned int major = (unsigned int)(api.ldapai_vendor_version / 10000); + unsigned int minor = + (((unsigned int)api.ldapai_vendor_version - major * 10000) + - patch) / 100; + curl_msnprintf(buf, bufsz, "%s/%u.%u.%u%s", + api.ldapai_vendor_name, major, minor, patch, flavor); + ldap_memfree(api.ldapai_vendor_name); + ber_memvfree((void **)api.ldapai_extensions); + } + else + curl_msnprintf(buf, bufsz, "LDAP/1"); #endif } -- 2.47.3