← Commit list

b9cbb61a53

Daniel Stenberg
Daniel Stenberg
2026-09-22
SUCCESS Duration: 437s

Subject

openldap: hand it a dup'd socket, not curl's own

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/openldap.c+52 -3
@@ -100,6 +100,7 @@ struct ldapconninfo {
Curl_send *send;
struct berval *servercred; /* SASL data from server. */
ldapstate state; /* Current machine state. */
+ curl_socket_t dupfd; /* duplicated socket */
int proto; /* LDAP_PROTO_TCP/LDAP_PROTO_UDP/LDAP_PROTO_IPC */
int msgid; /* Current message id. */
};
@@ -425,10 +426,21 @@ static int ldapsb_tls_remove(Sockbuf_IO_Desc *sbiod)
return 0;
}
-/* We do not need to do anything because libcurl does it already */
+/* if there is a duplicated socket to close, close it */
static int ldapsb_tls_close(Sockbuf_IO_Desc *sbiod)
{
- (void)sbiod;
+ struct Curl_easy *data = sbiod->sbiod_pvt;
+ if(data) {
+ struct connectdata *conn = data->conn;
+ if(conn) {
+ struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN);
+ if(li && (li->dupfd != CURL_SOCKET_BAD)) {
+ sclose(li->dupfd);
+ li->dupfd = CURL_SOCKET_BAD;
+ }
+ }
+ }
+
return 0;
}
@@ -607,6 +619,7 @@ static CURLcode oldap_connect(struct Curl_easy *data, bool *done)
result = CURLE_OUT_OF_MEMORY;
goto out;
}
+ li->dupfd = CURL_SOCKET_BAD;
result = Curl_conn_meta_set(conn, CURL_META_LDAP_CONN, li, oldap_conn_dtor);
if(result)
@@ -632,7 +645,43 @@ static CURLcode oldap_connect(struct Curl_easy *data, bool *done)
goto out;
}
- rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld);
+ {
+#ifdef _WIN32
+ SOCKET dupfd = INVALID_SOCKET;
+ WSAPROTOCOL_INFO pi;
+ if(WSADuplicateSocket(conn->sock[FIRSTSOCKET], GetCurrentProcessId(),
+ &pi))
+ ; /* error */
+ else
+ dupfd = CURL_SOCKET(pi.iAddressFamily, pi.iSocketType, pi.iProtocol);
+#else
+#ifdef F_DUPFD_CLOEXEC
+ int dupfd = fcntl(conn->sock[FIRSTSOCKET], F_DUPFD_CLOEXEC, 0);
+#else
+ int dupfd = dup(conn->sock[FIRSTSOCKET]);
+#ifdef HAVE_FCNTL
+ if((dupfd != CURL_SOCKET_BAD) &&
+ (fcntl(dupfd, F_SETFD, FD_CLOEXEC) < 0)) {
+ sclose(dupfd);
+ dupfd = CURL_SOCKET_BAD;
+ }
+#endif /* HAVE_FCNTL */
+#endif /* F_DUPFD_CLOEXEC */
+#endif /* _WIN32 */
+
+ if(dupfd == CURL_SOCKET_BAD) {
+ result = CURLE_COULDNT_CONNECT;
+ goto out;
+ }
+ rc = ldap_init_fd((ber_socket_t)dupfd, li->proto, hosturl, &li->ld);
+ if(rc)
+ sclose(dupfd);
+ else
+ /* store the socket, as when this is used by TLS we close this ourselves
+ and at this point the code does not yet know if this will use TLS or
+ not */
+ li->dupfd = dupfd;
+ }
if(rc) {
failf(data, "LDAP local: Cannot connect to %s, %s",
hosturl, ldap_err2string(rc));