From 8eeb738475f9df8e204cc98e7f777a78b4cebc0a Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: May 07 2014 16:49:53 +0000 Subject: Ticket 47792 - database plugins need a way to call betxn plugins Bug Description: Database plugins like "chaining" register their own add/mod/delete/modrdn functions. These new operation functions do not call the be/betxn plugins. Fix Description: Created two new private functions to call the pre & post be/betxn plugins. Added these functions to the chaining plugin. Maybe in the future these functions will be made public(slapi api). Also fixed a harmless startup/initialization memory leak. https://fedorahosted.org/389/ticket/47792 Jenkins: passed. Valgrind: passed. Reviewed by: rmeggins & lkrispenz (Thanks!!) (cherry picked from commit 9929b439b766e807ad77285e3b3babb514dde897) --- diff --git a/ldap/servers/plugins/chainingdb/cb_add.c b/ldap/servers/plugins/chainingdb/cb_add.c index 03d0fc9..3fd35df 100644 --- a/ldap/servers/plugins/chainingdb/cb_add.c +++ b/ldap/servers/plugins/chainingdb/cb_add.c @@ -142,8 +142,18 @@ chaining_back_add ( Slapi_PBlock *pb ) if ( slapi_op_abandoned( pb )) { cb_release_op_connection(cb->pool,ld,0); ldap_mods_free(mods,1); - if ( NULL != ctrls) - ldap_controls_free(ctrls); + ldap_controls_free(ctrls); + return -1; + } + + /* + * Call the backend preoperation plugins + */ + if((rc = slapi_plugin_call_preop_be_plugins(pb, SLAPI_PLUGIN_ADD_OP))){ + slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, "add (%s): pre betxn failed, error (%d)\n",dn,rc); + cb_release_op_connection(cb->pool,ld,0); + ldap_mods_free(mods,1); + ldap_controls_free(ctrls); return -1; } @@ -154,8 +164,7 @@ chaining_back_add ( Slapi_PBlock *pb ) /* Send LDAP operation to the remote host */ rc = ldap_add_ext( ld, dn, mods, ctrls, NULL, &msgid ); - if ( NULL != ctrls) - ldap_controls_free(ctrls); + ldap_controls_free(ctrls); if ( rc != LDAP_SUCCESS ) { slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, @@ -171,7 +180,6 @@ chaining_back_add ( Slapi_PBlock *pb ) * Poll the server for the results of the add operation. * Check for abandoned operation regularly. */ - while ( 1 ) { if (cb_check_forward_abandon(cb,pb,ld,msgid)) { @@ -186,11 +194,10 @@ chaining_back_add ( Slapi_PBlock *pb ) cb_send_ldap_result(pb,LDAP_OPERATIONS_ERROR, NULL, ldap_err2string(rc), 0, NULL); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); ldap_mods_free(mods,1); - if (res) - ldap_msgfree(res); + ldap_msgfree(res); return -1; - case 0: + case 0: if ((rc=cb_ping_farm(cb,cnx,endtime)) != LDAP_SUCCESS) { /* * does not respond. give up and return a @@ -202,14 +209,14 @@ chaining_back_add ( Slapi_PBlock *pb ) cb_send_ldap_result(pb,LDAP_OPERATIONS_ERROR, NULL, "FARM SERVER TEMPORARY UNAVAILABLE", 0, NULL); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); ldap_mods_free(mods,1); - if (res) - ldap_msgfree(res); + ldap_msgfree(res); return -1; } #ifdef CB_YIELD DS_Sleep(PR_INTERVAL_NO_WAIT); #endif break; + default: serverctrls=NULL; matched_msg=error_msg=NULL; @@ -231,13 +238,10 @@ chaining_back_add ( Slapi_PBlock *pb ) cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, ENDUSERMSG, 0, NULL ); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(parse_rc)); ldap_mods_free(mods,1); - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); - if (serverctrls) - ldap_controls_free(serverctrls); - /* jarnou: free referrals */ - if (referrals) - charray_free(referrals); + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); + ldap_controls_free(serverctrls); + charray_free(referrals); return -1; } @@ -255,36 +259,40 @@ chaining_back_add ( Slapi_PBlock *pb ) cb_send_ldap_result( pb, rc, matched_msg, ENDUSERMSG, 0, refs); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); ldap_mods_free(mods,1); - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); if (refs) ber_bvecfree(refs); - if (referrals) - charray_free(referrals); - if (serverctrls) - ldap_controls_free(serverctrls); + charray_free(referrals); + ldap_controls_free(serverctrls); return -1; } + /* Success */ ldap_mods_free(mods,1 ); cb_release_op_connection(cb->pool,ld,0); - /* Add control response sent by the farm server */ + /* Call the backend postoperation plugins */ + if((rc = slapi_plugin_call_postop_be_plugins(pb, SLAPI_PLUGIN_ADD_OP))){ + slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, "add (%s): post betxn failed, error (%d)\n",dn,rc); + } + /* Add control response sent by the farm server */ for (i=0; serverctrls && serverctrls[i];i++) slapi_pblock_set( pb, SLAPI_ADD_RESCONTROL, serverctrls[i]); if (serverctrls) ldap_controls_free(serverctrls); - /* jarnou: free matched_msg, error_msg, and referrals if necessary */ - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); - if (referrals) - charray_free(referrals); - cb_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL ); - slapi_entry_free(e); - slapi_pblock_set( pb, SLAPI_ADD_ENTRY, NULL ); - - return 0; + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); + charray_free(referrals); + cb_send_ldap_result( pb, rc, NULL, NULL, 0, NULL ); + if(rc == LDAP_SUCCESS){ + slapi_entry_free(e); + slapi_pblock_set( pb, SLAPI_ADD_ENTRY, NULL ); + return 0; + } else { + return -1; + } } } /* Never reached */ diff --git a/ldap/servers/plugins/chainingdb/cb_close.c b/ldap/servers/plugins/chainingdb/cb_close.c index ecac585..5d812a0 100644 --- a/ldap/servers/plugins/chainingdb/cb_close.c +++ b/ldap/servers/plugins/chainingdb/cb_close.c @@ -47,34 +47,45 @@ ** Should be followed by a cleanup */ -int cb_back_close( Slapi_PBlock *pb ) +static void +free_cb_backend(cb_backend *cb) { - Slapi_Backend * be; - cb_backend_instance * inst; - int rc; - - slapi_pblock_get( pb, SLAPI_BACKEND, &be ); - if (be == NULL) { - - cb_backend * cb = cb_get_backend_type(); - CB_ASSERT(cb!=NULL); - - slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP, cb->configDN, LDAP_SCOPE_BASE, - "(objectclass=*)",cb_config_modify_callback); - slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, cb->configDN, LDAP_SCOPE_BASE, - "(objectclass=*)",cb_config_modify_check_callback); - - slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_POSTOP, cb->configDN, LDAP_SCOPE_BASE, - "(objectclass=*)",cb_config_add_callback); - slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, cb->configDN, LDAP_SCOPE_BASE, - "(objectclass=*)",cb_config_add_check_callback); + if(cb){ + slapi_destroy_rwlock(cb->config.rwl_config_lock); + slapi_ch_free_string(&cb->pluginDN); + slapi_ch_free_string(&cb->configDN); + slapi_ch_array_free(cb->config.chainable_components); + slapi_ch_array_free(cb->config.chaining_components); + slapi_ch_array_free(cb->config.forward_ctrls); + slapi_ch_free((void **)&cb); + } +} - slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, cb->configDN, LDAP_SCOPE_BASE, - "(objectclass=*)",cb_config_search_callback); +int cb_back_close( Slapi_PBlock *pb ) +{ + Slapi_Backend *be; + cb_backend_instance *inst; + cb_backend *cb = cb_get_backend_type(); + int rc; - slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_POSTOP, cb->pluginDN, - LDAP_SCOPE_SUBTREE, CB_CONFIG_INSTANCE_FILTER, cb_config_add_instance_callback); + CB_ASSERT(cb != NULL); + slapi_pblock_get( pb, SLAPI_BACKEND, &be ); + if (be == NULL) { + slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP, cb->configDN, LDAP_SCOPE_BASE, + "(objectclass=*)",cb_config_modify_callback); + slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, cb->configDN, LDAP_SCOPE_BASE, + "(objectclass=*)",cb_config_modify_check_callback); + slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_POSTOP, cb->configDN, LDAP_SCOPE_BASE, + "(objectclass=*)",cb_config_add_callback); + slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, cb->configDN, LDAP_SCOPE_BASE, + "(objectclass=*)",cb_config_add_check_callback); + slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, cb->configDN, LDAP_SCOPE_BASE, + "(objectclass=*)",cb_config_search_callback); + slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_POSTOP, cb->pluginDN, + LDAP_SCOPE_SUBTREE, CB_CONFIG_INSTANCE_FILTER, cb_config_add_instance_callback); + + free_cb_backend(cb); return 0; } @@ -84,15 +95,15 @@ int cb_back_close( Slapi_PBlock *pb ) { const char * betype = slapi_be_gettype(be); if (!betype || strcasecmp(betype,CB_CHAINING_BACKEND_TYPE)) { - - slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, + slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, "Wrong database type.\n"); return 0; } } inst = cb_get_instance(be); - CB_ASSERT( inst!=NULL ); + CB_ASSERT( inst != NULL ); + free_cb_backend(cb); slapi_log_error( SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,"Stopping chaining database instance %s\n", inst->configDn); @@ -100,5 +111,5 @@ int cb_back_close( Slapi_PBlock *pb ) /* to clean up everything */ cb_instance_delete_config_callback(NULL, NULL,NULL, &rc, NULL, inst); - return 0; + return 0; } diff --git a/ldap/servers/plugins/chainingdb/cb_delete.c b/ldap/servers/plugins/chainingdb/cb_delete.c index 97807ef..1538589 100644 --- a/ldap/servers/plugins/chainingdb/cb_delete.c +++ b/ldap/servers/plugins/chainingdb/cb_delete.c @@ -137,7 +137,6 @@ chaining_back_delete ( Slapi_PBlock *pb ) if ( slapi_op_abandoned( pb )) { cb_release_op_connection(cb->pool,ld,0); - if ( NULL != ctrls) ldap_controls_free(ctrls); return -1; } @@ -147,12 +146,20 @@ chaining_back_delete ( Slapi_PBlock *pb ) endtime=current_time() + cb->max_idle_time; /* - * Send LDAP operation to the remote host + * Call the backend preoperation plugins */ + if((rc = slapi_plugin_call_preop_be_plugins(pb, SLAPI_PLUGIN_DEL_OP))){ + slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, "delete (%s): pre betxn failed, error (%d)\n",dn,rc); + cb_release_op_connection(cb->pool,ld,0); + ldap_controls_free(ctrls); + return -1; + } + /* + * Send LDAP operation to the remote host + */ rc = ldap_delete_ext( ld, dn, ctrls, NULL, &msgid ); - if ( NULL != ctrls) - ldap_controls_free(ctrls); + ldap_controls_free(ctrls); if ( rc != LDAP_SUCCESS ) { cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, ldap_err2string(rc), 0, NULL); @@ -171,8 +178,7 @@ chaining_back_delete ( Slapi_PBlock *pb ) cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, ldap_err2string(rc), 0, NULL); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); - if (res) - ldap_msgfree(res); + ldap_msgfree(res); return -1; case 0: if ((rc=cb_ping_farm(cb,cnx,endtime)) != LDAP_SUCCESS) { @@ -182,8 +188,7 @@ chaining_back_delete ( Slapi_PBlock *pb ) ldap_err2string(rc), 0, NULL);*/ cb_send_ldap_result(pb,LDAP_OPERATIONS_ERROR, NULL,"FARM SERVER TEMPORARY UNAVAILABLE", 0, NULL); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); - if (res) - ldap_msgfree(res); + ldap_msgfree(res); return -1; } #ifdef CB_YIELD @@ -207,13 +212,10 @@ chaining_back_delete ( Slapi_PBlock *pb ) cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, ENDUSERMSG, 0, NULL ); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(parse_rc)); - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); - if (serverctrls) - ldap_controls_free(serverctrls); - /* jarnou: free referrals */ - if (referrals) - charray_free(referrals); + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); + ldap_controls_free(serverctrls); + charray_free(referrals); return -1; } @@ -230,29 +232,29 @@ chaining_back_delete ( Slapi_PBlock *pb ) } cb_send_ldap_result( pb, rc, matched_msg, ENDUSERMSG, 0, refs); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); if (refs) ber_bvecfree(refs); - if (referrals) - charray_free(referrals); - if (serverctrls) - ldap_controls_free(serverctrls); + charray_free(referrals); + ldap_controls_free(serverctrls); return -1; } cb_release_op_connection(cb->pool,ld,0); + /* Call the backend postoperation plugins */ + if((rc = slapi_plugin_call_postop_be_plugins(pb, SLAPI_PLUGIN_DEL_OP))){ + slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, "delete (%s): post betxn failed, error (%d)\n",dn,rc); + } + /* Add control response sent by the farm server */ for (i=0; serverctrls && serverctrls[i];i++) slapi_pblock_set( pb, SLAPI_ADD_RESCONTROL, serverctrls[i]); - if (serverctrls) - ldap_controls_free(serverctrls); - /* jarnou: free matched_msg, error_msg, and referrals if necessary */ - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); - if (referrals) - charray_free(referrals); + ldap_controls_free(serverctrls); + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); + charray_free(referrals); cb_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL ); return 0; diff --git a/ldap/servers/plugins/chainingdb/cb_modify.c b/ldap/servers/plugins/chainingdb/cb_modify.c index 12d36da..db8a43c 100644 --- a/ldap/servers/plugins/chainingdb/cb_modify.c +++ b/ldap/servers/plugins/chainingdb/cb_modify.c @@ -106,7 +106,7 @@ chaining_back_modify ( Slapi_PBlock *pb ) if ( rc != LDAP_SUCCESS ) { cb_send_ldap_result( pb, rc, NULL, errbuf, 0, NULL ); - slapi_ch_free((void **)&errbuf); + slapi_ch_free_string(&errbuf); return -1; } } @@ -141,8 +141,7 @@ chaining_back_modify ( Slapi_PBlock *pb ) if ( slapi_op_abandoned( pb )) { cb_release_op_connection(cb->pool,ld,0); /* Don't free mods here: are freed at the do_modify level */ - if ( NULL != ctrls) - ldap_controls_free(ctrls); + ldap_controls_free(ctrls); return -1; } @@ -153,10 +152,19 @@ chaining_back_modify ( Slapi_PBlock *pb ) if (cb->max_idle_time>0) endtime=current_time() + cb->max_idle_time; + /* + * Call the backend preoperation plugins + */ + if((rc = slapi_plugin_call_preop_be_plugins(pb, SLAPI_PLUGIN_MOD_OP))){ + slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, "modify (%s): pre betxn failed, error (%d)\n",dn,rc); + cb_release_op_connection(cb->pool,ld,0); + ldap_controls_free(ctrls); + return -1; + } + /* Send LDAP operation to the remote host */ rc = ldap_modify_ext( ld, dn, mods, ctrls, NULL, &msgid ); - if ( NULL != ctrls) - ldap_controls_free(ctrls); + ldap_controls_free(ctrls); if ( rc != LDAP_SUCCESS ) { cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, ldap_err2string(rc), 0, NULL); @@ -176,8 +184,7 @@ chaining_back_modify ( Slapi_PBlock *pb ) cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, ldap_err2string(rc), 0, NULL); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); - if (res) - ldap_msgfree(res); + ldap_msgfree(res); return -1; case 0: if ((rc=cb_ping_farm(cb,cnx,endtime)) != LDAP_SUCCESS) { @@ -187,8 +194,7 @@ chaining_back_modify ( Slapi_PBlock *pb ) ldap_err2string(rc), 0, NULL);*/ cb_send_ldap_result(pb,LDAP_OPERATIONS_ERROR, NULL, "FARM SERVER TEMPORARY UNAVAILABLE", 0, NULL); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); - if (res) - ldap_msgfree(res); + ldap_msgfree(res); return -1; } #ifdef CB_YIELD @@ -214,13 +220,10 @@ chaining_back_modify ( Slapi_PBlock *pb ) cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, ENDUSERMSG, 0, NULL ); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(parse_rc)); - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); - if (serverctrls) - ldap_controls_free(serverctrls); - /* jarnou: free referrals */ - if (referrals) - charray_free(referrals); + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); + ldap_controls_free(serverctrls); + charray_free(referrals); return -1; } @@ -237,31 +240,30 @@ chaining_back_modify ( Slapi_PBlock *pb ) } cb_send_ldap_result( pb, rc, matched_msg, ENDUSERMSG, 0, refs); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); if (refs) ber_bvecfree(refs); - if (referrals) - charray_free(referrals); - if (serverctrls) + charray_free(referrals); ldap_controls_free(serverctrls); return -1; } cb_release_op_connection(cb->pool,ld,0); - /* Add control response sent by the farm server */ + /* Call the backend postoperation plugins */ + if((rc = slapi_plugin_call_postop_be_plugins(pb, SLAPI_PLUGIN_MOD_OP))){ + slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, "modify (%s): post betxn failed, error (%d)\n",dn,rc); + } + /* Add control response sent by the farm server */ for (i=0; serverctrls && serverctrls[i];i++) slapi_pblock_set( pb, SLAPI_ADD_RESCONTROL, serverctrls[i]); /* SLAPI_ADD_RESCONTROL dups controls */ - if (serverctrls) - ldap_controls_free(serverctrls); - /* jarnou: free matched_msg, error_msg, and referrals if necessary */ - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); - if (referrals) - charray_free(referrals); + ldap_controls_free(serverctrls); + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); + charray_free(referrals); cb_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL ); return 0; diff --git a/ldap/servers/plugins/chainingdb/cb_modrdn.c b/ldap/servers/plugins/chainingdb/cb_modrdn.c index 21903f7..b84fe57 100644 --- a/ldap/servers/plugins/chainingdb/cb_modrdn.c +++ b/ldap/servers/plugins/chainingdb/cb_modrdn.c @@ -109,7 +109,7 @@ chaining_back_modrdn ( Slapi_PBlock *pb ) if ( rc != LDAP_SUCCESS ) { cb_send_ldap_result( pb, rc, NULL, errbuf, 0, NULL ); - slapi_ch_free((void **)&errbuf); + slapi_ch_free_string(&errbuf); return -1; } } @@ -147,7 +147,6 @@ chaining_back_modrdn ( Slapi_PBlock *pb ) if ( slapi_op_abandoned( pb )) { cb_release_op_connection(cb->pool,ld,0); - if ( NULL != ctrls) ldap_controls_free(ctrls); return -1; } @@ -157,13 +156,22 @@ chaining_back_modrdn ( Slapi_PBlock *pb ) endtime=current_time() + cb->max_idle_time; /* + * Call the backend preoperation plugins + */ + if((rc = slapi_plugin_call_preop_be_plugins(pb, SLAPI_PLUGIN_MODRDN_OP))){ + slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, "modrdn (%s): pre betxn failed, error (%d)\n",ndn,rc); + cb_release_op_connection(cb->pool,ld,0); + ldap_controls_free(ctrls); + return -1; + } + + /* * Send LDAP operation to the remote host */ rc = ldap_rename ( ld, ndn, newrdn, slapi_sdn_get_dn(newsuperior), deleteoldrdn, ctrls, NULL, &msgid ); - if ( NULL != ctrls) - ldap_controls_free(ctrls); + ldap_controls_free(ctrls); if ( rc != LDAP_SUCCESS ) { cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, ldap_err2string(rc), 0, NULL); @@ -182,8 +190,7 @@ chaining_back_modrdn ( Slapi_PBlock *pb ) cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, ldap_err2string(rc), 0, NULL); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); - if (res) - ldap_msgfree(res); + ldap_msgfree(res); return -1; case 0: @@ -192,10 +199,9 @@ chaining_back_modrdn ( Slapi_PBlock *pb ) /*cb_send_ldap_result(pb,LDAP_OPERATIONS_ERROR, NULL, ldap_err2string(rc), 0, NULL);*/ - cb_send_ldap_result(pb,LDAP_OPERATIONS_ERROR, NULL, "FARM SERVER TEMPORARY UNAVAILABLE", 0, NULL); + cb_send_ldap_result(pb,LDAP_OPERATIONS_ERROR, NULL, "FARM SERVER TEMPORARY UNAVAILABLE", 0, NULL); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); - if (res) - ldap_msgfree(res); + ldap_msgfree(res); return -1; } #ifdef CB_YIELD @@ -221,13 +227,10 @@ chaining_back_modrdn ( Slapi_PBlock *pb ) cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, ENDUSERMSG, 0, NULL ); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(parse_rc)); - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); - if (serverctrls) - ldap_controls_free(serverctrls); - /* jarnou: free referrals */ - if (referrals) - charray_free(referrals); + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); + ldap_controls_free(serverctrls); + charray_free(referrals); return -1; } @@ -244,29 +247,29 @@ chaining_back_modrdn ( Slapi_PBlock *pb ) } cb_send_ldap_result( pb, rc, matched_msg, ENDUSERMSG, 0, refs); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); if (refs) ber_bvecfree(refs); - if (referrals) - charray_free(referrals); - if (serverctrls) - ldap_controls_free(serverctrls); + charray_free(referrals); + ldap_controls_free(serverctrls); return -1; } cb_release_op_connection(cb->pool,ld,0); + /* Call the backend postoperation plugins */ + if((rc = slapi_plugin_call_postop_be_plugins(pb, SLAPI_PLUGIN_MODRDN_OP))){ + slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, "modrdn (%s): post betxn failed, error (%d)\n",ndn,rc); + } + /* Add control response sent by the farm server */ for (i=0; serverctrls && serverctrls[i]; i++) slapi_pblock_set( pb, SLAPI_ADD_RESCONTROL, serverctrls[i]); - if (serverctrls) - ldap_controls_free(serverctrls); - /* jarnou: free matched_msg, error_msg, and referrals if necessary */ - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); - if (referrals) - charray_free(referrals); + ldap_controls_free(serverctrls); + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); + charray_free(referrals); cb_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL ); return 0; diff --git a/ldap/servers/plugins/chainingdb/cb_search.c b/ldap/servers/plugins/chainingdb/cb_search.c index faca2e3..9aecd26 100644 --- a/ldap/servers/plugins/chainingdb/cb_search.c +++ b/ldap/servers/plugins/chainingdb/cb_search.c @@ -242,8 +242,7 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb ) if ( slapi_op_abandoned( pb )) { cb_release_op_connection(cb->pool,ld,0); - if ( NULL != ctrls) - ldap_controls_free(ctrls); + ldap_controls_free(ctrls); return 1; } @@ -272,8 +271,7 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb ) rc = ldap_search_ext(ld ,target,scope,filter,attrs,attrsonly, ctrls, NULL, &timeout,sizelimit, &(ctx->msgid) ); - if ( NULL != ctrls) - ldap_controls_free(ctrls); + ldap_controls_free(ctrls); if ( LDAP_SUCCESS != rc ) { cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, ldap_err2string(rc), 0, NULL); @@ -307,8 +305,7 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb ) cb_send_ldap_result(pb,rc, NULL, NULL,0,NULL); } cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); - if (res) - ldap_msgfree(res); + ldap_msgfree(res); slapi_ch_free((void **)&ctx); return 1; @@ -322,8 +319,7 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb ) NULL,NULL, 0, NULL); /* Force connection close */ cb_release_op_connection(cb->pool,ld,1); - if (res) - ldap_msgfree(res); + ldap_msgfree(res); slapi_ch_free((void **)&ctx); return 1; } @@ -333,8 +329,7 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb ) cb_send_ldap_result(pb,LDAP_OPERATIONS_ERROR, NULL, ldap_err2string(rc), 0, NULL); cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc)); - if (res) - ldap_msgfree(res); + ldap_msgfree(res); slapi_ch_free((void **)&ctx); return 1; } @@ -391,12 +386,10 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb ) rc = -1; } - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); - if (serverctrls) - ldap_controls_free(serverctrls); - if (referrals) - charray_free(referrals); + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); + ldap_controls_free(serverctrls); + charray_free(referrals); if (rc != LDAP_SUCCESS) { cb_release_op_connection(cb->pool,ld, CB_LDAP_CONN_ERROR(rc)); @@ -547,8 +540,7 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb ) if (cb_check_forward_abandon(cb,pb,ctx->ld,ctx->msgid)) { /* cnx handle released */ - if (ctx->pending_result) - ldap_msgfree(ctx->pending_result); + ldap_msgfree(ctx->pending_result); slapi_ch_free((void **) &ctx); slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET,NULL ); slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY,NULL); @@ -589,8 +581,7 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb ) cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, ldap_err2string( rc ), 0, NULL); - if (res) - ldap_msgfree(res); + ldap_msgfree(res); cb_release_op_connection(cb->pool,ctx->ld,CB_LDAP_CONN_ERROR(rc)); slapi_ch_free((void **)&ctx); return -1; @@ -604,8 +595,7 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb ) cb_send_ldap_result(pb,LDAP_OPERATIONS_ERROR, NULL, ldap_err2string(rc), 0, NULL); - if (res) - ldap_msgfree(res); + ldap_msgfree(res); cb_release_op_connection(cb->pool,ctx->ld,CB_LDAP_CONN_ERROR(rc)); slapi_ch_free((void **)&ctx); return -1; @@ -751,12 +741,10 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb ) retcode=0; } - if (serverctrls) - ldap_controls_free(serverctrls); - slapi_ch_free((void **)&matched_msg); - slapi_ch_free((void **)&error_msg); - if (referrals) - charray_free(referrals); + ldap_controls_free(serverctrls); + slapi_ch_free_string(&matched_msg); + slapi_ch_free_string(&error_msg); + charray_free(referrals); cb_release_op_connection(cb->pool,ctx->ld,0); slapi_ch_free((void **)&ctx); diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c index b13ecbb..962276d 100644 --- a/ldap/servers/slapd/plugin.c +++ b/ldap/servers/slapd/plugin.c @@ -3275,3 +3275,96 @@ slapi_disordely_shutdown(PRBool set) } return (is_disordely_shutdown); } + +/* + * Allow "database" plugins to call the backend/backend txn plugins. + */ +int +slapi_plugin_call_preop_be_plugins(Slapi_PBlock *pb, int function) +{ + int be_func, betxn_func; + int rc = 0; + + switch(function){ + case SLAPI_PLUGIN_ADD_OP: + be_func = SLAPI_PLUGIN_BE_PRE_ADD_FN; + betxn_func = SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN; + break; + case SLAPI_PLUGIN_MOD_OP: + be_func = SLAPI_PLUGIN_BE_PRE_MODIFY_FN; + betxn_func = SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN; + break; + case SLAPI_PLUGIN_MODRDN_OP: + be_func = SLAPI_PLUGIN_BE_PRE_MODRDN_FN; + betxn_func = SLAPI_PLUGIN_BE_TXN_PRE_MODRDN_FN; + break; + case SLAPI_PLUGIN_DEL_OP: + be_func = SLAPI_PLUGIN_BE_PRE_DELETE_FN; + betxn_func = SLAPI_PLUGIN_BE_TXN_PRE_DELETE_FN; + break; + default: + /* invalid function */ + slapi_log_error(SLAPI_LOG_FATAL, "slapi_plugin_call_preop_betxn_plugins", + "Invalid function specified - backend plugins will not be called.\n"); + return 0; + } + + /* + * Call the be preop plugins. + */ + plugin_call_plugins(pb, be_func); + slapi_pblock_get(pb, SLAPI_RESULT_CODE, &rc); + + /* + * Call the betxn preop plugins. + */ + if (rc == LDAP_SUCCESS) { + plugin_call_plugins(pb, betxn_func); + slapi_pblock_get(pb, SLAPI_RESULT_CODE, &rc); + } + + return rc; +} + +int +slapi_plugin_call_postop_be_plugins(Slapi_PBlock *pb, int function) +{ + int be_func, betxn_func; + int rc = 0; + + switch(function){ + case SLAPI_PLUGIN_ADD_OP: + be_func = SLAPI_PLUGIN_BE_POST_ADD_FN; + betxn_func = SLAPI_PLUGIN_BE_TXN_POST_ADD_FN; + break; + case SLAPI_PLUGIN_MOD_OP: + be_func = SLAPI_PLUGIN_BE_POST_MODIFY_FN; + betxn_func = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN; + break; + case SLAPI_PLUGIN_MODRDN_OP: + be_func = SLAPI_PLUGIN_BE_POST_MODRDN_FN; + betxn_func = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN; + break; + case SLAPI_PLUGIN_DEL_OP: + be_func = SLAPI_PLUGIN_BE_POST_DELETE_FN; + betxn_func = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN; + break; + default: + /* invalid function */ + slapi_log_error(SLAPI_LOG_FATAL, "slapi_plugin_call_postop_betxn_plugins", + "Invalid function specified - backend plugins will not be called.\n"); + return 0; + } + + /* next, give the be txn plugins a crack at it */; + plugin_call_plugins(pb, betxn_func); + slapi_pblock_get(pb, SLAPI_RESULT_CODE, &rc); + + /* finally, give the be plugins a crack at it */ + plugin_call_plugins(pb, be_func); + if (rc == LDAP_SUCCESS) { + slapi_pblock_get(pb, SLAPI_RESULT_CODE, &rc); + } + + return rc; +} diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h index 28e6b97..596d4db 100644 --- a/ldap/servers/slapd/slapi-plugin.h +++ b/ldap/servers/slapd/slapi-plugin.h @@ -7172,6 +7172,12 @@ typedef struct slapi_plugindesc { corresponds to pb_search_ctrls */ #define SLAPI_SEARCH_CTRLS 198 +/* plugin be/betxn operations */ +#define SLAPI_PLUGIN_ADD_OP 199 +#define SLAPI_PLUGIN_MOD_OP 200 +#define SLAPI_PLUGIN_MODRDN_OP 201 +#define SLAPI_PLUGIN_DEL_OP 202 + #define SLAPI_RESULT_CODE 881 #define SLAPI_RESULT_TEXT 882 #define SLAPI_RESULT_MATCHED 883 diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h index 47c4557..0094bea 100644 --- a/ldap/servers/slapd/slapi-private.h +++ b/ldap/servers/slapd/slapi-private.h @@ -1262,6 +1262,40 @@ void DS_Sleep(PRIntervalTime ticks); /* plugin.c */ int plugin_enabled(const char *plugin_name, void *identity); +/** + * For "database" plugins that need to call preoperation backend & backend txn plugins. + * This function should be called right before the operation is performed. + * + * \param Slapi_PBLock object + * \param int operation + * + * Operations: + * SLAPI_PLUGIN_ADD_OP + * SLAPI_PLUGIN_MOD_OP + * SLAPI_PLUGIN_MODRDN_OP + * SLAPI_PLUGIN_DEL_OP + * + * \return zero on success, non-zero for failure + */ +int slapi_plugin_call_preop_be_plugins(Slapi_PBlock *pb, int operation); + +/** + * For "database" plugins that need to call postoperation backend & backend txn plugins. + * This function should be called right after the operation is performed. + * + * \param Slapi_PBLock object + * \param int operation + * + * Operations: + * SLAPI_PLUGIN_ADD_OP + * SLAPI_PLUGIN_MOD_OP + * SLAPI_PLUGIN_MODRDN_OP + * SLAPI_PLUGIN_DEL_OP + * + * \return zero on success, non-zero for failure + */ +int slapi_plugin_call_postop_be_plugins(Slapi_PBlock *pb, int operation); + /* protect_db.c */ /* is_slapd_running() * returns 1 if slapd is running, 0 if not, -1 on error