瀏覽代碼

Bug 710377 - Import with chain-on-update crashes ns-slapd

If you perform an import using ldif2db for a suffix that is configured
to chain-on-update, ns-slapd will crash due to a NULL pointer dereference.
The problem is that the chaining backends are not loaded when ns-slapd is
run in ldif2db mode.  This results in the chaining backend being NULL.

To fix this issue, we should return the local backend in the chain-on-update
distribution function when we are unable to find a backend by name.  We can
assume that this only occurs when an import is being done.  This should
allow one to use ldif2db to do an offline replica initialization when
chain-on-update is configured.
Nathan Kinder 14 年之前
父節點
當前提交
39714d3d79
共有 1 個文件被更改,包括 38 次插入21 次删除
  1. 38 21
      ldap/servers/plugins/replication/replutil.c

+ 38 - 21
ldap/servers/plugins/replication/replutil.c

@@ -850,32 +850,49 @@ repl_chain_on_update(Slapi_PBlock *pb, Slapi_DN * target_dn,
 	for (ii = 0; ii < be_count; ++ii)
 	{
 		Slapi_Backend *be = slapi_be_select_by_instance_name(mtn_be_names[ii]);
-		if (slapi_be_is_flag_set(be,SLAPI_BE_FLAG_REMOTE_DATA))
-		{
-			chaining_backend = ii;
-		}
-		else
-		{
-			local_backend = ii;
-			if (mtn_be_states[ii] == SLAPI_BE_STATE_ON)
+		if (be) {
+			if (slapi_be_is_flag_set(be,SLAPI_BE_FLAG_REMOTE_DATA))
 			{
-				local_online = PR_TRUE;
+				chaining_backend = ii;
+			}
+			else
+			{
+				local_backend = ii;
+				if (mtn_be_states[ii] == SLAPI_BE_STATE_ON)
+				{
+					local_online = PR_TRUE;
+				}
 			}
-		}
 #ifdef DEBUG_CHAIN_ON_UPDATE
-		if (is_internal) {
-			slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "repl_chain_on_update: conn=-1 op=%d be "
-				"%s is the %s backend and is %s\n", opid,
-				mtn_be_names[ii], (chaining_backend == ii) ? "chaining" : "local",
-				(mtn_be_states[ii] == SLAPI_BE_STATE_ON) ? "online" : "offline");
-		} else {
-			slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "repl_chain_on_update: conn=%" PRIu64 " op=%d be "
-				"%s is the %s backend and is %s\n", connid, opid,
-				mtn_be_names[ii], (chaining_backend == ii) ? "chaining" : "local",
-				(mtn_be_states[ii] == SLAPI_BE_STATE_ON) ? "online" : "offline");
+			if (is_internal) {
+				slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "repl_chain_on_update: conn=-1 op=%d be "
+					"%s is the %s backend and is %s\n", opid,
+					mtn_be_names[ii], (chaining_backend == ii) ? "chaining" : "local",
+					(mtn_be_states[ii] == SLAPI_BE_STATE_ON) ? "online" : "offline");
+			} else {
+				slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "repl_chain_on_update: conn=%" PRIu64 " op=%d be "
+					"%s is the %s backend and is %s\n", connid, opid,
+					mtn_be_names[ii], (chaining_backend == ii) ? "chaining" : "local",
+					(mtn_be_states[ii] == SLAPI_BE_STATE_ON) ? "online" : "offline");
 
-		}
+			}
+#endif
+		} else {
+			/* A chaining backend will not be found during import.  We will just return the
+			 * local backend in this case, which seems like the right thing to do to allow
+			 * offline replication initialization. */
+#ifdef DEBUG_CHAIN_ON_UPDATE
+			if (is_internal) {
+				slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "repl_chain_on_update: conn=-1 op=%d be "
+					"%s not found.  Assuming it is the chaining backend and we are doing an import.\n",
+					opid, mtn_be_names[ii]);
+			} else {
+				slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "repl_chain_on_update: conn=%" PRIu64 " op=%d be "
+					"%s not found.  Assuming it is the chaining backend and we are doing an import.\n",
+					connid, opid, mtn_be_names[ii]);
+			}
 #endif
+		}
 	}
 
 	/* if no chaining backends are defined, just use the local one */