Sfoglia il codice sorgente

Ticket 48388 - db2ldif -r segfaults from time to time

Bug Description:  db2ldif starts all the plugins before generating
                  the ldif file.  If the retro changelog is enabled
                  and it starts to trim itself the server can crash
                  when cos tries to process the retrocl triming
                  operations.

Fix Description:  First, fix the NULL dereferences in COS.  Then
                  when doing a "db2ldif -r" only startup the
                  plugins that "db2ldif -r" needs (which is just
                  the replication plugin and its dependencies).

                  Revised the plugin_startall() function to remove
                  unused parameters (start_backends & global_plugins)

                  Also did a little code clean up slapi_utf8casecmp.

https://fedorahosted.org/389/ticket/48388

Valgrind: passed

Reviewed by: nhosoi(Thanks!)
Mark Reynolds 10 anni fa
parent
commit
c7c3d59632

+ 16 - 1
ldap/servers/plugins/cos/cos_cache.c

@@ -3034,7 +3034,8 @@ static int cos_cache_attr_compare(const void *e1, const void *e2)
 	cosTemplates *pTemplate1 = (cosTemplates*)pAttr1->pParent;
         
 	/* Now compare the names of the attributes */
-	com_Result = slapi_utf8casecmp((unsigned char*)(*(cosAttributes**)e1)->pAttrName,(unsigned char*)(*(cosAttributes**)e2)->pAttrName);
+	com_Result = slapi_utf8casecmp((unsigned char*)(*(cosAttributes**)e1)->pAttrName,
+	                               (unsigned char*)(*(cosAttributes**)e2)->pAttrName);
 	if(0 == com_Result){
 		/* Now compare the cosPriorities */
 		com_Result = pTemplate->cosPriority - pTemplate1->cosPriority;
@@ -3047,6 +3048,13 @@ static int cos_cache_attr_compare(const void *e1, const void *e2)
 
 static int cos_cache_string_compare(const void *e1, const void *e2)
 {
+	if (!e1 && e2) {
+		return 1;
+	} else if (e1 && !e2) {
+		return -1;
+	} else if (!e1 && !e2) {
+		return 0;
+	}
 	return slapi_utf8casecmp((*(unsigned char**)e1),(*(unsigned char**)e2));
 }
 
@@ -3054,6 +3062,13 @@ static int cos_cache_template_index_compare(const void *e1, const void *e2)
 {
 	int ret = 0;
 
+	if (!e1 && e2) {
+		return 1;
+	} else if (e1 && !e2) {
+		return -1;
+	} else if (!e1 && !e2) {
+		return 0;
+	}
 	if(0 == slapi_dn_issuffix((const char*)e1,*(const char**)e2))
 		ret = slapi_utf8casecmp(*(unsigned char**)e2,(unsigned char*)e1);
 	else

+ 19 - 8
ldap/servers/slapd/main.c

@@ -1051,7 +1051,7 @@ main( int argc, char **argv)
 		pw_exp_init ();
 
 		plugin_print_lists();
-		plugin_startall(argc, argv, 1 /* Start Backends */, 1 /* Start Globals */);
+		plugin_startall(argc, argv, NULL /* specific plugin list */);
                 compute_plugins_started();
 		if (housekeeping_start((time_t)0, NULL) == NULL) {
 			return_value = 1;
@@ -2216,13 +2216,24 @@ slapd_exemode_db2ldif(int argc, char** argv)
 		else
 			pb.pb_server_running = 0;
 	
-	    if (db2ldif_dump_replica) {
-			eq_init();					/* must be done before plugins started */
-	        ps_init_psearch_system();   /* must come before plugin_startall() */
-	        plugin_startall(argc, argv, 1 /* Start Backends */,
-								  1 /* Start Globals */); 
-			eq_start();					/* must be done after plugins started */
-	    }
+		if (db2ldif_dump_replica) {
+			char **plugin_list = NULL;
+			char *repl_plg_name = "Multimaster Replication Plugin";
+
+			/*
+			 * Only start the necessary plugins for "db2ldif -r"
+			 *
+			 * We need replication, but replication has its own
+			 * dependencies
+			 */
+			plugin_get_plugin_dependencies(repl_plg_name, &plugin_list);
+
+			eq_init(); /* must be done before plugins started */
+			ps_init_psearch_system(); /* must come before plugin_startall() */
+			plugin_startall(argc, argv, plugin_list);
+			eq_start(); /* must be done after plugins started */
+			charray_free(plugin_list);
+		}
 	  
 	    pb.pb_ldif_file = NULL;
 	    if ( archive_name ) { /* redirect stdout to this file: */

+ 76 - 9
ldap/servers/slapd/plugin.c

@@ -1390,6 +1390,47 @@ plugin_free_plugin_dep_config(plugin_dep_config **cfg)
 	}
 }
 
+/*
+ * Take a given plugin and recursively set all the plugin dependency names
+ */
+void
+plugin_get_plugin_dependencies(char *plugin_name, char ***names)
+{
+    entry_and_plugin_t *ep = dep_plugin_entries;
+    char **depends = NULL;
+    char *dep_attr = "nsslapd-plugin-depends-on-named";
+    int i;
+
+    /* Add the original plugin name to the list */
+    if (!charray_inlist(*names, plugin_name)){
+        charray_add(names, slapi_ch_strdup(plugin_name));
+    }
+
+    /* Find the plugin and grab its dependencies */
+    while(ep)
+    {
+        if (ep->plugin){
+            if(strcasecmp(ep->plugin->plg_name, plugin_name) == 0){
+                /* We found our plugin, now grab its dependencies */
+                depends = slapi_entry_attr_get_charray(ep->e, dep_attr);
+                break;
+            }
+        }
+        ep = ep->next;
+    }
+
+    if (depends){
+        /* Add the plugin's dependencies */
+        charray_merge_nodup(names, depends, 1);
+
+        /* Add each dependency's dependencies */
+        for (i = 0; depends[i]; i++){
+            /* recurse */
+            plugin_get_plugin_dependencies(depends[i], names);
+        }
+        slapi_ch_array_free(depends);
+    }
+}
 
 /*
  * plugin_dependency_startall()
@@ -1407,7 +1448,7 @@ plugin_free_plugin_dep_config(plugin_dep_config **cfg)
  */
 
 static int 
-plugin_dependency_startall(int argc, char** argv, char *errmsg, int operation)
+plugin_dependency_startall(int argc, char** argv, char *errmsg, int operation, char** plugin_list)
 {
 	int ret = 0;
 	Slapi_PBlock pb;
@@ -1419,7 +1460,7 @@ plugin_dependency_startall(int argc, char** argv, char *errmsg, int operation)
 	int i = 0;  /* general index iterator */
 	plugin_dep_type the_plugin_type;
 	int index = 0;
-	char * value;
+	char *value = NULL;
 	int plugins_started;
 	int num_plg_started;
 	struct slapdplugin *plugin;
@@ -1435,25 +1476,50 @@ plugin_dependency_startall(int argc, char** argv, char *errmsg, int operation)
 	global_plugin_callbacks_enabled = 0;
 
 	/* Count the plugins so we can allocate memory for the config array */
-    while(ep)
+	while(ep)
 	{
 		total_plugins++;
-
 		ep = ep->next;
 	}
 
 	/* allocate the config array */
 	config = (plugin_dep_config*)slapi_ch_calloc(total_plugins + 1, sizeof(plugin_dep_config));
-
 	ep = dep_plugin_entries;
+	if (plugin_list){
+		/* We have a plugin list, so we need to reset the plugin count */
+		total_plugins = 0;
+	}
 
 	/* Collect relevant config */
-    while(ep)
+	while(ep)
 	{
 		plugin = ep->plugin;
 
-		if(plugin == 0)
+		if(plugin == 0){
+			ep = ep->next;
 			continue;
+		}
+
+		if (plugin_list){
+			/*
+			 * We have a specific list of plugins to start, skip the others...
+			 */
+			int found = 0;
+			for (i = 0; plugin_list[i]; i++){
+				if (strcasecmp(plugin->plg_name, plugin_list[i]) == 0){
+					found = 1;
+					break;
+				}
+			}
+
+			if (!found){
+				/* Skip this plugin, it's not in the list */
+				ep = ep->next;
+				continue;
+			} else {
+				total_plugins++;
+			}
+		}
 
 		pblock_init(&pb);
 		slapi_pblock_set( &pb, SLAPI_ARGC, &argc);
@@ -1824,12 +1890,13 @@ plugin_dependency_closeall()
  *              stuff is done with. So this function goes through and starts all plugins
  */
 void
-plugin_startall(int argc, char** argv, int start_backends, int start_global)
+plugin_startall(int argc, char** argv, char **plugin_list)
 {
 	/* initialize special plugin structures */
 	default_plugin_init ();
 
-	plugin_dependency_startall(argc, argv, "plugin startup failed\n", SLAPI_PLUGIN_START_FN);
+	plugin_dependency_startall(argc, argv, "plugin startup failed\n",
+	                           SLAPI_PLUGIN_START_FN, plugin_list);
 }
 
 /*

+ 6 - 3
ldap/servers/slapd/proto-slap.h

@@ -865,11 +865,14 @@ int plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid *group,
 int plugin_call_exop_plugins( Slapi_PBlock *pb, char *oid );
 const char *plugin_extended_op_oid2string( const char *oid );
 void plugin_closeall(int close_backends, int close_globals);
-void plugin_startall(int argc,char **argv,int start_backends, int start_global);
+void plugin_startall(int argc, char **argv, char **plugin_list);
+void plugin_get_plugin_dependencies(char *plugin_name, char ***names);
 struct slapdplugin *get_plugin_list(int plugin_list_index);
-PRBool plugin_invoke_plugin_sdn (struct slapdplugin *plugin, int operation, Slapi_PBlock *pb, Slapi_DN *target_spec);
+PRBool plugin_invoke_plugin_sdn (struct slapdplugin *plugin, int operation,
+                                 Slapi_PBlock *pb, Slapi_DN *target_spec);
 struct slapdplugin *plugin_get_by_name(char *name);
-struct slapdplugin *plugin_get_pwd_storage_scheme(char *name, int len, int index);
+struct slapdplugin *plugin_get_pwd_storage_scheme(char *name, int len,
+                                                  int index);
 char *plugin_get_pwd_storage_scheme_list(int index);
 int plugin_add_descriptive_attributes( Slapi_Entry *e,
 		struct slapdplugin *plugin );

+ 17 - 17
ldap/servers/slapd/utf8compare.c

@@ -2115,15 +2115,15 @@ slapi_utf8casecmp(unsigned char *s0, unsigned char *s1)
 
     d0 = d1 = NULL;
     if (s0 == NULL || *s0 == '\0') {
-	if (s1 == NULL || *s1 == '\0') {
-	    rval = 0;
-	} else {
-	    rval = -1;	/* regardless s1, s0 < s1 */
-	}
-	goto end;
+        if (s1 == NULL || *s1 == '\0') {
+            rval = 0;
+        } else {
+            rval = -1;	/* regardless s1, s0 < s1 */
+        }
+        goto end;
     } else if (s1 == NULL || *s1 == '\0') {
-	rval = 1;	/* regardless s0, s0 > s1 */
-	goto end;
+        rval = 1;	/* regardless s0, s0 > s1 */
+        goto end;
     }
 
     has8_s0 = slapi_has8thBit(s0);
@@ -2141,9 +2141,9 @@ slapi_utf8casecmp(unsigned char *s0, unsigned char *s1)
     d0 = slapi_utf8StrToLower(s0);
     d1 = slapi_utf8StrToLower(s1);
     if (d0 == NULL || d1 == NULL || /* either is not a UTF-8 string */
-	(d0 && *d0 == '\0') || (d1 && *d1 == '\0')) {	
-	rval = strcasecmp((char *)s0, (char *)s1);
-	goto end;
+        (d0 && *d0 == '\0') || (d1 && *d1 == '\0')) {
+        rval = strcasecmp((char *)s0, (char *)s1);
+        goto end;
     }
 
     p0 = d0;
@@ -2157,25 +2157,25 @@ slapi_utf8casecmp(unsigned char *s0, unsigned char *s1)
         n0 = (unsigned char *)ldap_utf8next((char *)p0);
         n1 = (unsigned char *)ldap_utf8next((char *)p1);
         if (n0 > t0 || n1 > t1) {
-	    break;
-	}
+            break;
+        }
 
         i0 = n0 - p0;
         i1 = n1 - p1;
-	rval = i0 - i1;
+        rval = i0 - i1;
         if (rval) {         /* length is different */
             goto end;
-	}
+        }
 
         /* i0 == i1: same length */
         for (x0 = p0, x1 = p1; x0 < n0; x0++, x1++) {
             rval = *x0 - *x1;
             if (rval) {
                 goto end;
-	    }
+            }
         }
 
-	p0 = n0; p1 = n1;	/* goto next */
+        p0 = n0; p1 = n1; /* goto next */
     }
     /* finished scanning the shared part and check the leftover */
     l0 = t0 - n0;