From 94cd54db82e79bf4666fc3ced1f3a4ced6651a94 Mon Sep 17 00:00:00 2001
From: William Brown <firstyear@redhat.com>
Date: Tue, 2 May 2017 16:02:20 +1000
Subject: [PATCH] Ticket 49185 - Fix leaks in compute init and dblayer

Bug Description:  There were a number of leaks in compute_init
and dblayer related to db2archive.

Fix Description:  Resolve the leaks by fixing the free of of
dblayer close, and the double init of compute.

https://pagure.io/389-ds-base/issue/49185

Author: wibrown

Review by: ???
---
 ldap/servers/slapd/back-ldbm/dblayer.c | 11 +++--
 ldap/servers/slapd/main.c              | 14 ++-----
 ldap/servers/slapd/plugin.c            | 73 ++++++++++++++++++++++------------
 ldap/servers/slapd/task.c              | 12 +++---
 4 files changed, 62 insertions(+), 48 deletions(-)

diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 979323a..edc9804 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -1346,6 +1346,7 @@ dblayer_start(struct ldbminfo *li, int dbmode)
     /* li->li_directory comes from nsslapd-directory */
     /* dblayer_home_directory is freed in dblayer_post_close.
      * li_directory needs to live beyond dblayer. */
+    slapi_ch_free(&priv->dblayer_home_directory);
     priv->dblayer_home_directory = slapi_ch_strdup(li->li_directory); 
     priv->dblayer_cachesize = li->li_dbcachesize;
     priv->dblayer_lock_config = li->li_dblock;
@@ -2274,7 +2275,7 @@ dblayer_get_aux_id2entry_ext(backend *be, DB **ppDB, DB_ENV **ppEnv,
             "dblayer_get_aux_id2entry_ext", "No dblayer info: persistent id2entry is not available\n");
         goto done;
     }
-    priv = (dblayer_private *)slapi_ch_malloc(sizeof(dblayer_private));
+    priv = (dblayer_private *)slapi_ch_calloc(1, sizeof(dblayer_private));
     memcpy(priv, opriv, sizeof(dblayer_private));
     priv->dblayer_spin_count = 0;
 
@@ -2630,7 +2631,6 @@ int dblayer_post_close(struct ldbminfo *li, int dbmode)
     dblayer_private *priv = 0;
     int return_value = 0;
     dblayer_private_env *pEnv;
-    int shutdown = g_get_shutdown();
 
     PR_ASSERT(NULL != li);
     priv = (dblayer_private*)li->li_dblayer_private;
@@ -2663,10 +2663,8 @@ int dblayer_post_close(struct ldbminfo *li, int dbmode)
         charray_free(priv->dblayer_data_directories);
         priv->dblayer_data_directories = NULL;
     }
-    if(shutdown){
-        slapi_ch_free_string(&priv->dblayer_dbhome_directory);
-        slapi_ch_free_string(&priv->dblayer_home_directory);
-    }
+    slapi_ch_free_string(&priv->dblayer_dbhome_directory);
+    slapi_ch_free_string(&priv->dblayer_home_directory);
 
     return return_value;
 }
@@ -7176,6 +7174,7 @@ dblayer_restore_file_update(struct ldbminfo *li, char *directory)
     PRFileDesc *prfd;
     char *fname = dblayer_restore_file_name(li);
     dblayer_file_open(fname, PR_RDWR, li->li_mode, &prfd);
+    slapi_ch_free(&fname);
     if (prfd) {
         char *line = slapi_ch_smprintf("restore of %s succeeded", directory);
         slapi_write_buffer(prfd, line, strlen(line));
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index ba1f5e8..3364a01 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -755,7 +755,8 @@ main( int argc, char **argv)
 		/* -sduloutre: must be done before any internal search */
 		/* do it before splitting off to other modes too -robey */
 		/* -richm: must be done before reading config files */
-		if (0 != (return_value = compute_init())) {
+		return_value = compute_init();
+		if (return_value != 0) {
 			slapi_log_err(SLAPI_LOG_EMERG, "main", "Initialization Failed 0 %d\n",return_value);
 			exit (1);
 		}
@@ -2457,11 +2458,7 @@ slapd_exemode_db2archive(void)
 				"Shutting down due to possible conflicts with other slapd processes\n");
 		return 1;
 	}
-	if (compute_init()) {
-		slapi_log_err(SLAPI_LOG_ERR, "slapd_exemode_db2archive",
-			"Initialization Failed 0 %d\n",return_value);
-		return 1;
-	}
+
 	if (!is_quiet) {
 		slapd_ldap_debug |= LDAP_DEBUG_BACKLDBM;
 	}
@@ -2509,11 +2506,6 @@ slapd_exemode_archive2db(void)
 		       "Shutting down due to possible conflicts with other slapd processes\n");
 	    return 1;
 	}
-	if (compute_init()) {
-		slapi_log_err(SLAPI_LOG_ERR, "slapd_exemode_archive2db",
-			"Initialization Failed 0 %d\n",return_value);
-		return 1;
-	}
 
 	if (!is_quiet) {
 		slapd_ldap_debug |= LDAP_DEBUG_BACKLDBM;
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index 6131c4b..d6e9914 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -1953,6 +1953,24 @@ plugin_dependency_closeall(void)
 	}
 }
 
+void
+plugin_freeall(void)
+{
+	struct slapdplugin *plugin = NULL;
+	struct slapdplugin *plugin_next = NULL;
+	int type = 0;
+
+	/* look everywhere for other plugin functions with the plugin id */
+	for(type = 0; type < PLUGIN_LIST_GLOBAL_MAX; type++){
+		plugin = global_plugin_list[type];
+		while(plugin){
+			plugin_next = plugin->plg_next;
+            plugin_free(plugin);
+            plugin = plugin_next;
+		}
+	}
+}
+
 /*
  * Function: plugin_dependency_freeall
  *
@@ -1971,11 +1989,12 @@ plugin_dependency_freeall()
 	while (iterp) {
 		nextp = iterp->next;
 		slapi_entry_free(iterp->e);
-		plugin_free(iterp->plugin);
+		/* plugin_free(iterp->plugin); */
 		slapi_ch_free((void **)&iterp);
 		iterp = nextp;
 	}
 	dep_plugin_entries = NULL;
+    plugin_freeall();
 }
 
 /***********************************************************
@@ -2370,8 +2389,9 @@ plugin_get_type_and_list(
         return( 1 ); /* unknown plugin type - pass to backend */
 	}
 
-	if (plugin_list_index >= 0)
+	if (plugin_list_index >= 0) {
 		*plugin_list = &global_plugin_list[plugin_list_index];
+    }
 
 	return 0;
 }
@@ -4206,34 +4226,37 @@ struct slapdplugin *plugin_get_by_name(char *name)
 struct slapi_componentid *
 generate_componentid ( struct slapdplugin * pp , char * name )
 {
-        struct slapi_componentid * idp;
-
-        idp = (struct slapi_componentid *) slapi_ch_calloc(1, sizeof( *idp ));
-        if ( pp )
-                idp->sci_plugin=pp;
-        else
-                idp->sci_plugin=(struct slapdplugin *) plugin_get_server_plg();
-
-        if ( name )
-                idp->sci_component_name = slapi_ch_strdup(name);
-        else
-                /* Use plugin dn */
-                idp->sci_component_name = plugin_get_dn( idp->sci_plugin );
-
-	if (idp->sci_component_name)
-		slapi_dn_normalize(idp->sci_component_name);
-        return idp;
+    struct slapi_componentid * idp;
+
+    idp = (struct slapi_componentid *) slapi_ch_calloc(1, sizeof( *idp ));
+    if ( pp ) {
+            idp->sci_plugin=pp;
+    } else {
+            idp->sci_plugin=(struct slapdplugin *) plugin_get_server_plg();
+    }
+
+    if ( name ) {
+            idp->sci_component_name = slapi_ch_strdup(name);
+    } else {
+            /* Use plugin dn */
+            idp->sci_component_name = plugin_get_dn( idp->sci_plugin );
+    }
+
+    if (idp->sci_component_name) {
+        slapi_dn_normalize(idp->sci_component_name);
+    }
+    return idp;
 }
 
 void release_componentid ( struct slapi_componentid * id )
 {
-        if ( id ) {
-                if ( id->sci_component_name ) {
-                        slapi_ch_free((void **)&id->sci_component_name);
-                        id->sci_component_name=NULL;
-                }
-                slapi_ch_free((void **)&id);
+    if ( id ) {
+        if ( id->sci_component_name ) {
+            slapi_ch_free((void **)&id->sci_component_name);
+            id->sci_component_name=NULL;
         }
+        slapi_ch_free((void **)&id);
+    }
 }
 
 /* used in main.c if -V flag is given */
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
index defae2b..afaaebd 100644
--- a/ldap/servers/slapd/task.c
+++ b/ldap/servers/slapd/task.c
@@ -893,7 +893,8 @@ static int task_import_add(Slapi_PBlock *pb __attribute__((unused)),
      * otherwise, we use included/excluded suffix list to specify a backend.
      */
     if (NULL == instance_name) {
-        char **instances, **ip;
+        char **instances = NULL;
+        char **ip;
         int counter;
 
         if (slapi_lookup_instance_name_by_suffixes(include, exclude,
@@ -909,11 +910,10 @@ static int task_import_add(Slapi_PBlock *pb __attribute__((unused)),
                 ;
 
             if (counter == 1){
-                instance_name = *instances;
-                nameFrombe_name = *instances;
-                
-            }
-            else if (counter == 0) {
+                instance_name = slapi_ch_strdup(*instances);
+                nameFrombe_name = instance_name;
+                charray_free(instances);
+            } else if (counter == 0) {
                 slapi_log_err(SLAPI_LOG_ERR,
                           "task_import_add", "No backend instance is specified.\n");
                 *returncode = LDAP_OBJECT_CLASS_VIOLATION;
-- 
1.8.3.1

