sachidananda sahu wrote:
Hi Howard,
Some clarification with respect to this statement "The context is per-process state, not per-thread state. No threads should be trying to destroy the context."
Consider in my process i have two threads, each want to connect to their respective LDAP server. As two LDAP server so two different certificate and two different tls context. In that case that process specific global variable will be overwritten, considering concurrent case (One thread is in ldap_int_tls_start as part of allocation and further use and other thread in ldap_unbind_ext--->ldap_ld_free-->ldap_int_tls_destroy(&ld->ld_options );).
Irrelevant. If you're going to read the code, read it more carefully.
So the concern is two treads connecting to two LDAP server independently (starting ldo_tls_ctx from same global variable or ldap_unbind_ext where they free the ldo_tls_ctx) . The same global variable getting used through two different LDAP server connection, two different ld context. So clarity needed with this concurrent scenario,
- Here we are storing the local context ldo_tls_ctx with after extracting from global option structure ldo_tls_ctx.
ldap_int_tls_connect( LDAP *ld, LDAPConn *conn, const char *host ) { ... Sockbuf *sb = conn->lconn_sb; int err; tls_session *ssl = NULL;
if ( HAS_TLS( sb )) { ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl ); } else { struct ldapoptions *lo; tls_ctx *ctx;
*ctx = ld->ld_options.ldo_tls_ctx;* ------------------------- ssl = alloc_handle( ctx, 0 );
if ( ssl == NULL ) return -1;
#ifdef LDAP_DEBUG ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug, LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" ); #endif ber_sockbuf_add_io( sb, tls_imp->ti_sbio, LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
lo = LDAP_INT_GLOBAL_OPT(); if( ctx == NULL ) { *ctx = lo->ldo_tls_ctx; -------------------- Storing the global context in to ld specific local context. * ld->ld_options.ldo_tls_ctx = ctx; tls_ctx_ref( ctx );
You have ignored this line. ^^
} ... }
- ldap_ld_free is deleting that ld specific context but inside that the context is same as global option structure ldo_tls_ctx.
int ldap_ld_free( LDAP *ld, int close, LDAPControl **sctrls, LDAPControl **cctrls ) { ... #ifdef HAVE_TLS * ldap_int_tls_destroy( &ld->ld_options ); ----------------- Destroying the tls_ctx inside this function, though it is extracting from ld, but it carries the address of global option ldo_tls_ctx as per point 1.* #endif ..... }
void *ldap_int_tls_destroy*( struct ldapoptions *lo ) { if ( lo->ldo_tls_ctx ) { *ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx ); lo->ldo_tls_ctx = NULL;* } ... }