Commit 844cc979 authored by Howard Chu's avatar Howard Chu
Browse files

More for re-entrant LDAP* handles. Works much better.

parent 074b1a0d
......@@ -32,8 +32,7 @@ static int do_abandon LDAP_P((
ber_int_t origid,
ber_int_t msgid,
LDAPControl **sctrls,
LDAPControl **cctrls,
int lock));
LDAPControl **cctrls));
/*
* ldap_abandon_ext - perform an ldap extended abandon operation.
......@@ -65,10 +64,17 @@ ldap_abandon_ext(
#endif
/* check client controls */
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
rc = ldap_int_client_controls( ld, cctrls );
if( rc != LDAP_SUCCESS ) return rc;
if( rc == LDAP_SUCCESS )
rc = do_abandon( ld, msgid, msgid, sctrls, cctrls );
return do_abandon( ld, msgid, msgid, sctrls, cctrls, 1 );
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
return rc;
}
......@@ -102,8 +108,7 @@ do_abandon(
ber_int_t origid,
ber_int_t msgid,
LDAPControl **sctrls,
LDAPControl **cctrls,
int lock)
LDAPControl **cctrls)
{
BerElement *ber;
int i, err, sendabandon;
......@@ -120,9 +125,6 @@ do_abandon(
sendabandon = 1;
#ifdef LDAP_R_COMPILE
if ( lock ) ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
/* find the request that we are abandoning */
for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
if ( lr->lr_msgid == msgid ) { /* this message */
......@@ -130,12 +132,9 @@ do_abandon(
}
if ( lr->lr_origid == msgid ) {/* child: abandon it */
(void) do_abandon( ld,
msgid, lr->lr_msgid, sctrls, cctrls, 0 );
msgid, lr->lr_msgid, sctrls, cctrls );
}
}
#ifdef LDAP_R_COMPILE
if ( lock ) ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
if ( lr != NULL ) {
if ( origid == msgid && lr->lr_parent != NULL ) {
......@@ -149,7 +148,17 @@ do_abandon(
}
}
if ( ldap_msgdelete( ld, msgid ) == 0 ) {
/* ldap_msgdelete locks the res_mutex. Give up the req_mutex
* while we're in there.
*/
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
err = ldap_msgdelete( ld, msgid );
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
if ( err == 0 ) {
ld->ld_errno = LDAP_SUCCESS;
return LDAP_SUCCESS;
}
......@@ -167,6 +176,7 @@ do_abandon(
ld->ld_errno = LDAP_NO_MEMORY;
} else {
LDAP_NEXT_MSGID(ld, i);
#ifdef LDAP_CONNECTIONLESS
if ( LDAP_IS_UDP(ld) ) {
err = ber_write( ber, ld->ld_options.ldo_peer,
......@@ -177,14 +187,14 @@ do_abandon(
char *dn = ld->ld_options.ldo_cldapdn;
if (!dn) dn = "";
err = ber_printf( ber, "{isti", /* '}' */
++ld->ld_msgid, dn,
i, dn,
LDAP_REQ_ABANDON, msgid );
} else
#endif
{
/* create a message to send */
err = ber_printf( ber, "{iti", /* '}' */
++ld->ld_msgid,
i,
LDAP_REQ_ABANDON, msgid );
}
......@@ -221,18 +231,12 @@ do_abandon(
sb = ld->ld_sb;
}
#ifdef LDAP_R_COMPILE
if ( lock ) ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
if ( ber_flush( sb, ber, 1 ) != 0 ) {
ld->ld_errno = LDAP_SERVER_DOWN;
err = -1;
} else {
err = 0;
}
#ifdef LDAP_R_COMPILE
if ( lock ) ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
}
}
}
......
......@@ -98,6 +98,7 @@ ldap_add_ext(
{
BerElement *ber;
int i, rc;
ber_int_t id;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ENTRY, "ldap_add_ext\n", 0, 0, 0 );
......@@ -119,8 +120,9 @@ ldap_add_ext(
return ld->ld_errno;
}
LDAP_NEXT_MSGID(ld, id);
rc = ber_printf( ber, "{it{s{", /* '}}}' */
++ld->ld_msgid, LDAP_REQ_ADD, dn );
id, LDAP_REQ_ADD, dn );
if ( rc == -1 ) {
ld->ld_errno = LDAP_ENCODING_ERROR;
......@@ -163,7 +165,7 @@ ldap_add_ext(
}
/* send the message */
*msgidp = ldap_send_initial_request( ld, LDAP_REQ_ADD, dn, ber );
*msgidp = ldap_send_initial_request( ld, LDAP_REQ_ADD, dn, ber, id );
if(*msgidp < 0)
return ld->ld_errno;
......
......@@ -54,6 +54,7 @@ ldap_compare_ext(
{
int rc;
BerElement *ber;
ber_int_t id;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ENTRY, "ldap_compare\n", 0, 0, 0 );
......@@ -76,9 +77,11 @@ ldap_compare_ext(
return( LDAP_NO_MEMORY );
}
if ( ber_printf( ber, "{it{s{sON}N}", /* '}' */
++ld->ld_msgid,
LDAP_REQ_COMPARE, dn, attr, bvalue ) == -1 )
LDAP_NEXT_MSGID(ld, id);
rc = ber_printf( ber, "{it{s{sON}N}", /* '}' */
id,
LDAP_REQ_COMPARE, dn, attr, bvalue );
if ( rc == -1 )
{
ld->ld_errno = LDAP_ENCODING_ERROR;
ber_free( ber, 1 );
......@@ -99,7 +102,7 @@ ldap_compare_ext(
/* send the message */
*msgidp = ldap_send_initial_request( ld, LDAP_REQ_COMPARE, dn, ber );
*msgidp = ldap_send_initial_request( ld, LDAP_REQ_COMPARE, dn, ber, id );
return ( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
}
......
......@@ -47,6 +47,7 @@ ldap_delete_ext(
{
int rc;
BerElement *ber;
ber_int_t id;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ENTRY, "ldap_delete_ext\n", 0,0,0 );
......@@ -69,8 +70,10 @@ ldap_delete_ext(
return( ld->ld_errno );
}
if ( ber_printf( ber, "{its", /* '}' */
++ld->ld_msgid, LDAP_REQ_DELETE, dn ) == -1 )
LDAP_NEXT_MSGID( ld, id );
rc = ber_printf( ber, "{its", /* '}' */
id, LDAP_REQ_DELETE, dn );
if ( rc == -1 )
{
ld->ld_errno = LDAP_ENCODING_ERROR;
ber_free( ber, 1 );
......@@ -90,7 +93,7 @@ ldap_delete_ext(
}
/* send the message */
*msgidp = ldap_send_initial_request( ld, LDAP_REQ_DELETE, dn, ber );
*msgidp = ldap_send_initial_request( ld, LDAP_REQ_DELETE, dn, ber, id );
if(*msgidp < 0)
return ld->ld_errno;
......
......@@ -283,6 +283,9 @@ ldap_parse_result(
if(referralsp != NULL) *referralsp = NULL;
if(serverctrls != NULL) *serverctrls = NULL;
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
#endif
/* Find the next result... */
for ( lm = r; lm != NULL; lm = lm->lm_chain ) {
/* skip over entries and references */
......@@ -296,6 +299,9 @@ ldap_parse_result(
if( lm == NULL ) {
ld->ld_errno = LDAP_NO_RESULTS_RETURNED;
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
#endif
return ld->ld_errno;
}
......@@ -410,6 +416,9 @@ ldap_parse_result(
if ( freeit ) {
ldap_msgfree( r );
}
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
#endif
return( errcode );
}
......@@ -43,6 +43,7 @@ ldap_extended_operation(
{
BerElement *ber;
int rc;
ber_int_t id;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ENTRY, "ldap_extended_operation\n", 0,0,0 );
......@@ -67,15 +68,16 @@ ldap_extended_operation(
return( ld->ld_errno );
}
LDAP_NEXT_MSGID( ld, id );
if ( reqdata != NULL ) {
rc = ber_printf( ber, "{it{tstON}", /* '}' */
++ld->ld_msgid, LDAP_REQ_EXTENDED,
id, LDAP_REQ_EXTENDED,
LDAP_TAG_EXOP_REQ_OID, reqoid,
LDAP_TAG_EXOP_REQ_VALUE, reqdata );
} else {
rc = ber_printf( ber, "{it{tsN}", /* '}' */
++ld->ld_msgid, LDAP_REQ_EXTENDED,
id, LDAP_REQ_EXTENDED,
LDAP_TAG_EXOP_REQ_OID, reqoid );
}
......@@ -98,7 +100,7 @@ ldap_extended_operation(
}
/* send the message */
*msgidp = ldap_send_initial_request( ld, LDAP_REQ_EXTENDED, NULL, ber );
*msgidp = ldap_send_initial_request( ld, LDAP_REQ_EXTENDED, NULL, ber, id );
return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
}
......
......@@ -62,6 +62,7 @@ ldap_kerberos_bind1( LDAP *ld, LDAP_CONST char *dn )
char *cred;
int rc;
ber_len_t credlen;
ber_int_t id;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ENTRY, "ldap_kerberos_bind1\n", 0, 0, 0 );
......@@ -88,8 +89,9 @@ ldap_kerberos_bind1( LDAP *ld, LDAP_CONST char *dn )
return( -1 );
}
LDAP_NEXT_MSGID( ld, id );
/* fill it in */
rc = ber_printf( ber, "{it{istoN}N}", ++ld->ld_msgid, LDAP_REQ_BIND,
rc = ber_printf( ber, "{it{istoN}N}", id, LDAP_REQ_BIND,
ld->ld_version, dn, LDAP_AUTH_KRBV41, cred, credlen );
if ( rc == -1 ) {
......@@ -103,7 +105,7 @@ ldap_kerberos_bind1( LDAP *ld, LDAP_CONST char *dn )
/* send the message */
return ( ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber ));
return ( ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber, id ));
}
int
......@@ -148,6 +150,7 @@ ldap_kerberos_bind2( LDAP *ld, LDAP_CONST char *dn )
char *cred;
int rc;
ber_len_t credlen;
ber_int_t id;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ENTRY, "ldap_kerberos_bind2\n", 0, 0, 0 );
......@@ -174,11 +177,11 @@ ldap_kerberos_bind2( LDAP *ld, LDAP_CONST char *dn )
return( -1 );
}
LDAP_NEXT_MSGID( ld, id );
/* fill it in */
rc = ber_printf( ber, "{it{istoN}N}", ++ld->ld_msgid, LDAP_REQ_BIND,
rc = ber_printf( ber, "{it{istoN}N}", id, LDAP_REQ_BIND,
ld->ld_version, dn, LDAP_AUTH_KRBV42, cred, credlen );
LDAP_FREE( cred );
if ( rc == -1 ) {
......@@ -188,7 +191,7 @@ ldap_kerberos_bind2( LDAP *ld, LDAP_CONST char *dn )
}
/* send the message */
return ( ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber ));
return ( ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber, id ));
}
/* synchronous bind to DSA using kerberos */
......
......@@ -327,6 +327,15 @@ LDAP_V( ldap_pvt_thread_mutex_t ) ldap_int_sasl_mutex;
#endif
#endif
#ifdef LDAP_R_COMPILE
#define LDAP_NEXT_MSGID(ld, id) \
ldap_pvt_thread_mutex_lock( &(ld)->ld_req_mutex ); \
id = ++(ld)->ld_msgid; \
ldap_pvt_thread_mutex_unlock( &(ld)->ld_req_mutex )
#else
#define LDAP_NEXT_MSGID(ld, id) id = ++(ld)->ld_msgid
#endif
/*
* in init.c
*/
......@@ -449,7 +458,7 @@ LDAP_F (int) ldap_connect_to_path( LDAP *ld, Sockbuf *sb,
* in request.c
*/
LDAP_F (ber_int_t) ldap_send_initial_request( LDAP *ld, ber_tag_t msgtype,
const char *dn, BerElement *ber );
const char *dn, BerElement *ber, ber_int_t msgid );
LDAP_F (BerElement *) ldap_alloc_ber_with_options( LDAP *ld );
LDAP_F (void) ldap_set_ber_options( LDAP *ld, BerElement *ber );
......@@ -485,7 +494,8 @@ LDAP_F (BerElement *) ldap_build_search_req LDAP_P((
LDAPControl **sctrls,
LDAPControl **cctrls,
ber_int_t timelimit,
ber_int_t sizelimit ));
ber_int_t sizelimit,
ber_int_t *msgidp));
/*
......
......@@ -52,6 +52,7 @@ ldap_modify_ext( LDAP *ld,
{
BerElement *ber;
int i, rc;
ber_int_t id;
/*
* A modify request looks like this:
......@@ -86,8 +87,9 @@ ldap_modify_ext( LDAP *ld,
return( LDAP_NO_MEMORY );
}
if ( ber_printf( ber, "{it{s{" /*}}}*/, ++ld->ld_msgid, LDAP_REQ_MODIFY, dn )
== -1 ) {
LDAP_NEXT_MSGID( ld, id );
rc = ber_printf( ber, "{it{s{" /*}}}*/, id, LDAP_REQ_MODIFY, dn );
if ( rc == -1 ) {
ld->ld_errno = LDAP_ENCODING_ERROR;
ber_free( ber, 1 );
return( ld->ld_errno );
......@@ -131,7 +133,7 @@ ldap_modify_ext( LDAP *ld,
}
/* send the message */
*msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODIFY, dn, ber );
*msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODIFY, dn, ber, id );
return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
}
......
......@@ -67,6 +67,7 @@ ldap_rename(
{
BerElement *ber;
int rc;
ber_int_t id;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ENTRY, "ldap_rename\n", 0, 0, 0 );
......@@ -83,6 +84,7 @@ ldap_rename(
return( LDAP_NO_MEMORY );
}
LDAP_NEXT_MSGID( ld, id );
if( newSuperior != NULL ) {
/* must be version 3 (or greater) */
if ( ld->ld_version < LDAP_VERSION3 ) {
......@@ -90,15 +92,14 @@ ldap_rename(
ber_free( ber, 1 );
return( ld->ld_errno );
}
rc = ber_printf( ber, "{it{ssbtsN}", /* '}' */
++ld->ld_msgid, LDAP_REQ_MODDN,
id, LDAP_REQ_MODDN,
dn, newrdn, (ber_int_t) deleteoldrdn,
LDAP_TAG_NEWSUPERIOR, newSuperior );
} else {
rc = ber_printf( ber, "{it{ssbN}", /* '}' */
++ld->ld_msgid, LDAP_REQ_MODDN,
id, LDAP_REQ_MODDN,
dn, newrdn, (ber_int_t) deleteoldrdn );
}
......@@ -122,7 +123,7 @@ ldap_rename(
}
/* send the message */
*msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODRDN, dn, ber );
*msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODRDN, dn, ber, id );
if( *msgidp < 0 ) {
return( ld->ld_errno );
......
......@@ -82,7 +82,8 @@ ldap_send_initial_request(
LDAP *ld,
ber_tag_t msgtype,
const char *dn,
BerElement *ber )
BerElement *ber,
ber_int_t msgid)
{
LDAPURLDesc *servers;
int rc;
......@@ -133,8 +134,14 @@ ldap_send_initial_request(
return LDAP_PARAM_ERROR;
}
#endif
rc = ldap_send_server_request( ld, ber, ld->ld_msgid, NULL,
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
rc = ldap_send_server_request( ld, ber, msgid, NULL,
servers, NULL, NULL );
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
if (servers)
ldap_free_urllist(servers);
return(rc);
......@@ -233,17 +240,11 @@ ldap_send_server_request(
* request to be in WRITING state.
*/
rc = 0;
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
if ( ld->ld_requests &&
ld->ld_requests->lr_status == LDAP_REQST_WRITING &&
ldap_int_flush_request( ld, ld->ld_requests ) < 0 ) {
rc = -1;
}
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
if ( rc ) return rc;
if (( lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ))) ==
......@@ -276,9 +277,6 @@ ldap_send_server_request(
lr->lr_origid = lr->lr_msgid;
}
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
if (( lr->lr_next = ld->ld_requests ) != NULL ) {
lr->lr_next->lr_prev = lr;
}
......@@ -289,9 +287,6 @@ ldap_send_server_request(
if ( ldap_int_flush_request( ld, lr ) == -1 ) {
msgid = -1;
}
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
return( msgid );
}
......@@ -606,7 +601,6 @@ ldap_dump_requests_and_responses( LDAP *ld )
}
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
#endif
fprintf( stderr, "** Response Queue:\n" );
if (( lm = ld->ld_responses ) == NULL ) {
......@@ -625,9 +619,6 @@ ldap_dump_requests_and_responses( LDAP *ld )
}
}
}
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
#endif
}
#endif /* LDAP_DEBUG */
......@@ -849,7 +840,8 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
srv->lud_dn = LDAP_STRDUP( "" );
}
ber = re_encode_request( ld, origreq->lr_ber, ++ld->ld_msgid,
LDAP_NEXT_MSGID( ld, rc );
ber = re_encode_request( ld, origreq->lr_ber, rc,
sref, srv, &rinfo.ri_request );
if( ber == NULL ) {
......@@ -871,8 +863,15 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
/* Send the new request to the server - may require a bind */
rinfo.ri_msgid = origreq->lr_origid;
rinfo.ri_url = refarray[i];
if ( (rc = ldap_send_server_request( ld, ber, ld->ld_msgid,
origreq, srv, NULL, &rinfo )) < 0 ) {
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
rc = ldap_send_server_request( ld, ber, ld->ld_msgid,
origreq, srv, NULL, &rinfo );
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
if ( rc < 0 ) {
/* Failure, try next referral in the list */
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ERR,
......@@ -1047,8 +1046,9 @@ ldap_chase_referrals( LDAP *ld,
*hadrefp = 1;
LDAP_NEXT_MSGID( ld, rc );
ber = re_encode_request( ld, origreq->lr_ber,
++ld->ld_msgid, sref, srv, &rinfo.ri_request );
rc, sref, srv, &rinfo.ri_request );
if( ber == NULL ) {
return -1 ;
......@@ -1059,8 +1059,14 @@ ldap_chase_referrals( LDAP *ld,
rinfo.ri_msgid = origreq->lr_origid;
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
rc = ldap_send_server_request( ld, ber, ld->ld_msgid,
lr, srv, NULL, &rinfo );
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
LDAP_FREE( rinfo.ri_url );
......
......@@ -97,6 +97,7 @@ ldap_result(
LDAPMessage **result )
{
LDAPMessage *lm;
int rc;
assert( ld != NULL );
assert( result != NULL );
......@@ -107,15 +108,22 @@ ldap_result(
Debug( LDAP_DEBUG_TRACE, "ldap_result msgid %d\n", msgid, 0, 0 );
#endif
lm = chkResponseList(ld, msgid, all);
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
#endif
lm = chkResponseList(ld, msgid, all);
if ( lm == NULL ) {
return( wait4msg( ld, msgid, all, timeout, result ) );
rc = wait4msg( ld, msgid, all, timeout, result );
} else {
*result = lm;
ld->ld_errno = LDAP_SUCCESS;
rc = lm->lm_msgtype;
}
*result = lm;
ld->ld_errno = LDAP_SUCCESS;
return( lm->lm_msgtype );
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
#endif
return( rc );
}
static LDAPMessage *
......@@ -141,9 +149,6 @@ chkResponseList(
msgid, all, 0 );
#endif
lastlm = NULL;
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
#endif
for ( lm = ld->ld_responses; lm != NULL; lm = nextlm ) {
nextlm = lm->lm_next;
......@@ -210,9 +215,6 @@ chkResponseList(
}
lm->lm_next = NULL;
}
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
#endif