From: Pierangelo Masarati Date: Fri, 4 Nov 2005 01:42:11 +0000 (+0000) Subject: add a giant mutex around the ldapinfo structure to serialize chaining (need to check... X-Git-Tag: OPENLDAP_REL_ENG_2_2_MP~105 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=1ec4cf7bbaa15f2ed00d899f8835bdbdd2327750;p=openldap add a giant mutex around the ldapinfo structure to serialize chaining (need to check for deadlocks...) --- diff --git a/servers/slapd/back-ldap/chain.c b/servers/slapd/back-ldap/chain.c index 8f702c85b9..a0dbb581c2 100644 --- a/servers/slapd/back-ldap/chain.c +++ b/servers/slapd/back-ldap/chain.c @@ -69,6 +69,8 @@ typedef struct ldap_chain_t { #define LDAP_CHAIN_F_NONE 0x00U #define LDAP_CHAIN_F_CHAINING 0x01U + ldap_pvt_thread_mutex_t lc_mutex; + #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR LDAPControl lc_chaining_ctrl; char lc_chaining_ctrlflag; @@ -259,7 +261,10 @@ ldap_chain_op( { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; - struct ldapinfo li, *lip = lc->lc_li; + + struct ldapinfo *lip = lc->lc_li; + char *save_url = NULL; + SlapReply rs2 = { 0 }; /* NOTE: returned if ref is empty... */ int rc = LDAP_OTHER; @@ -272,12 +277,14 @@ ldap_chain_op( if ( lip->url != NULL ) { op->o_bd->be_private = lip; - rc = ( *op_f )( op, rs ); + rc = ( *op_f )( op, &rs2 ); + rs->sr_err = rs2.sr_err; goto done; } - li = *lip; - op->o_bd->be_private = &li; + save_url = lip->url; + lip->url = NULL; + op->o_bd->be_private = lip; /* if we parse the URI then by no means * we can cache stuff or reuse connections, @@ -321,26 +328,29 @@ Document: draft-ietf-ldapbis-protocol-27.txt save_dn = srv->lud_dn; srv->lud_dn = ""; srv->lud_scope = LDAP_SCOPE_DEFAULT; - li.url = ldap_url_desc2str( srv ); + lip->url = ldap_url_desc2str( srv ); srv->lud_dn = save_dn; ldap_free_urldesc( srv ); - if ( li.url == NULL ) { + if ( lip->url == NULL ) { /* try next */ rc = LDAP_OTHER; continue; } - rc = ( *op_f )( op, rs ); + rc = ( *op_f )( op, &rs2 ); + rs->sr_err = rs2.sr_err; - ldap_memfree( li.url ); - li.url = NULL; + ldap_memfree( lip->url ); + lip->url = NULL; if ( rc == LDAP_SUCCESS && rs->sr_err == LDAP_SUCCESS ) { break; } } + lip->url = save_url; + done:; #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR (void)chaining_control_remove( op, &ctrls ); @@ -362,7 +372,7 @@ ldap_chain_response( Operation *op, SlapReply *rs ) struct berval ndn = op->o_ndn; ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; - struct ldapinfo li, *lip = lc->lc_li; + struct ldapinfo *lip = lc->lc_li; #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR int sr_err = rs->sr_err; @@ -402,6 +412,8 @@ ldap_chain_response( Operation *op, SlapReply *rs ) } #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ + ldap_pvt_thread_mutex_lock( &lc->lc_mutex ); + /* * TODO: add checks on who/when chain operations; e.g.: * a) what identities are authorized @@ -441,8 +453,6 @@ ldap_chain_response( Operation *op, SlapReply *rs ) } break; case LDAP_REQ_ADD: - /* slap_mods2entry () should be called in do_add() */ - assert( op->ora_e->e_attrs != NULL ); rc = ldap_chain_op( op, rs, lback->bi_op_add, ref ); break; case LDAP_REQ_DELETE: @@ -462,6 +472,8 @@ ldap_chain_response( Operation *op, SlapReply *rs ) struct berval *curr = ref, odn = op->o_req_dn, ondn = op->o_req_ndn; + char *save_url = NULL; + SlapReply rs2 = { 0 }; #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR LDAPControl **ctrls = NULL; @@ -473,9 +485,9 @@ ldap_chain_response( Operation *op, SlapReply *rs ) sc2.sc_response = ldap_chain_cb_search_response; - li = *lip; - li.url = NULL; - op->o_bd->be_private = &li; + save_url = lip->url; + lip->url = NULL; + op->o_bd->be_private = lip; /* if we parse the URI then by no means * we can cache stuff or reuse connections, @@ -504,8 +516,8 @@ ldap_chain_response( Operation *op, SlapReply *rs ) save_dn = srv->lud_dn; srv->lud_dn = ""; srv->lud_scope = LDAP_SCOPE_DEFAULT; - li.url = ldap_url_desc2str( srv ); - if ( li.url != NULL ) { + lip->url = ldap_url_desc2str( srv ); + if ( lip->url != NULL ) { ber_str2bv_x( save_dn, 0, 1, &op->o_req_dn, op->o_tmpmemctx ); ber_dupbv_x( &op->o_req_ndn, &op->o_req_dn, @@ -515,7 +527,7 @@ ldap_chain_response( Operation *op, SlapReply *rs ) srv->lud_dn = save_dn; ldap_free_urldesc( srv ); - if ( li.url == NULL ) { + if ( lip->url == NULL ) { /* try next */ rs->sr_err = LDAP_OTHER; continue; @@ -524,10 +536,11 @@ ldap_chain_response( Operation *op, SlapReply *rs ) /* FIXME: should we also copy filter and scope? * according to RFC3296, no */ - rc = lback->bi_op_search( op, rs ); + rc = lback->bi_op_search( op, &rs2 ); + rs->sr_err = rs2.sr_err; - ldap_memfree( li.url ); - li.url = NULL; + ldap_memfree( lip->url ); + lip->url = NULL; op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); @@ -545,6 +558,8 @@ ldap_chain_response( Operation *op, SlapReply *rs ) (void)chaining_control_remove( op, &ctrls ); #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ + lip->url = save_url; + op->o_req_dn = odn; op->o_req_ndn = ondn; rs->sr_type = REP_SEARCHREF; @@ -613,6 +628,8 @@ dont_chain:; op->o_ndn = ndn; rs->sr_ref = ref; + ldap_pvt_thread_mutex_unlock( &lc->lc_mutex ); + return rc; } @@ -1074,6 +1091,8 @@ ldap_chain_db_init( lc = ch_malloc( sizeof( ldap_chain_t ) ); memset( lc, 0, sizeof( ldap_chain_t ) ); + ldap_pvt_thread_mutex_init( &lc->lc_mutex ); + bd.be_private = NULL; rc = lback->bi_db_init( &bd ); lc->lc_li = (struct ldapinfo *)bd.be_private; @@ -1108,7 +1127,7 @@ ldap_chain_db_destroy( be->be_private = (void *)lc->lc_li; rc = lback->bi_db_destroy( be ); - lc->lc_li = be->be_private; + ldap_pvt_thread_mutex_destroy( &lc->lc_mutex ); ch_free( lc ); on->on_bi.bi_private = NULL; be->be_private = private;