浏览代码

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!!)

Mark Reynolds 11 年之前
父节点
当前提交
9929b439b7

+ 42 - 34
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 */

+ 2 - 2
ldap/servers/plugins/chainingdb/cb_close.c

@@ -56,6 +56,7 @@ free_cb_backend(cb_backend *cb)
         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);
     }
@@ -68,8 +69,6 @@ int cb_back_close( Slapi_PBlock *pb )
 	cb_backend *cb = cb_get_backend_type();
 	int rc;
 
-
-
 	slapi_pblock_get( pb, SLAPI_BACKEND, &be );
 	if (be == NULL) {
 
@@ -103,6 +102,7 @@ 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, "Wrong database type.\n");
+			free_cb_backend(cb);
 			return 0;
 		}
 	}

+ 30 - 28
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;

+ 31 - 29
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;

+ 32 - 29
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;
 	}
@@ -156,14 +155,23 @@ chaining_back_modrdn ( 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_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;

+ 16 - 28
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);

+ 93 - 0
ldap/servers/slapd/plugin.c

@@ -4399,3 +4399,96 @@ slapi_plugin_running(Slapi_PBlock *pb)
 
     return rc;
 }
+
+/*
+ *  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;
+}

+ 6 - 0
ldap/servers/slapd/slapi-plugin.h

@@ -7231,6 +7231,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

+ 34 - 0
ldap/servers/slapd/slapi-private.h

@@ -1267,6 +1267,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