>From b8441b19fc66871a54e8be98b37867e385e15928 Mon Sep 17 00:00:00 2001
From: Rich Megginson <rmeggins@redhat.com>
Date: Wed, 8 Jul 2009 09:57:04 -0600
Subject: [PATCH] Reduce noise reported by valgrind
 valgrind is a very useful tool - however, the directory server produces a lot
 of false positives that have to be suppressed in order to get to the useful
 information.  These patches attempt to reduce some of that noise.
 1) aclparse - should calculate the length of the string _after_ trimming the
 spaces
 2) something about random number generation causes some of the bits to be uninitialized, and valgrind doesn't like it - this patch doesn't eliminate the error, just reduces it
 3) use initialized memory when generating hashes - also remove "magic numbers"
 4) bin.c - slapi_value_get_string must not be used with unterminated (binary) values
 5) we get these odd valgrind reports from deep within bdb about invalid reads and uninitialized memory - I thought perhaps because we were initializing DBT structures with = {0} which the bdb docs says is not sufficient - they recommend memset or bzero
 6) There are some small memory leaks during attrcrypt initialization and in error cases
 7) error message in ldif2ldbm.c was attempting to print the Slapi_DN structure rather than getting the char *dn
 8) After we call NSS_Initialize, we must call the NSS shutdown functions to clean up the caches and other data structures, otherwise NSS will leak memory.  This is harmless since it happens at exit, but valgrind reports hundreds of memory leaks.  The solution is to make sure we go through a single exit point after NSS_Initialize.  This means many places that just called exit() must instead return with a real return value.  This mostly affected main.c, detach.c, and a couple of other places called during startup.
 9) minor memory leaks in mapping tree initialization
 10) sasl_map.c - should not call this in referral mode
 11) minor memory leaks during ssl init

---
 ldap/servers/plugins/acl/aclparse.c           |    3 +-
 ldap/servers/plugins/acl/aclutil.c            |   11 +-
 ldap/servers/plugins/pwdstorage/sha_pwd.c     |   35 +++--
 ldap/servers/plugins/pwdstorage/ssha_pwd.c    |   28 ++--
 ldap/servers/plugins/syntaxes/bin.c           |    6 +-
 ldap/servers/slapd/back-ldbm/id2entry.c       |    6 +-
 ldap/servers/slapd/back-ldbm/idl_new.c        |   13 ++-
 ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c |   13 ++-
 ldap/servers/slapd/back-ldbm/ldif2ldbm.c      |    3 +-
 ldap/servers/slapd/detach.c                   |   11 +-
 ldap/servers/slapd/main.c                     |  190 ++++++++++++++-----------
 ldap/servers/slapd/mapping_tree.c             |   36 +++---
 ldap/servers/slapd/proto-slap.h               |    4 +-
 ldap/servers/slapd/sasl_map.c                 |    5 +
 ldap/servers/slapd/ssl.c                      |    7 +-
 15 files changed, 217 insertions(+), 154 deletions(-)

diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c
index 8855623..57fd5ae 100644
--- a/ldap/servers/plugins/acl/aclparse.c
+++ b/ldap/servers/plugins/acl/aclparse.c
@@ -609,11 +609,10 @@ normalize_nextACERule:
 	** for deny rule. We will never need more 2 times 
 	** the len.
 	*/
+	__acl_strip_leading_space(&tmp_str);
 	len = strlen (tmp_str);
 	s_acestr = acestr = slapi_ch_calloc ( 1, 2 * len);
 
-	__acl_strip_leading_space(&tmp_str);
-
 	/*
 	 * Now it's something like:
 	 * allow (all) groupdn = "ldap:///cn=Domain Administrators, o=$dn.o, o=ISP";
diff --git a/ldap/servers/plugins/acl/aclutil.c b/ldap/servers/plugins/acl/aclutil.c
index 599fdbd..a93a53a 100644
--- a/ldap/servers/plugins/acl/aclutil.c
+++ b/ldap/servers/plugins/acl/aclutil.c
@@ -442,10 +442,13 @@ acl_gen_err_msg(int access, char *edn, char *attr, char **errbuf)
 short
 aclutil_gen_signature ( short c_signature )
 {
-	short	o_signature;
-	o_signature = c_signature ^ (slapi_rand() % 32768);
-	if (!o_signature)
-		o_signature = c_signature ^ (slapi_rand() % 32768);
+	short	o_signature = 0;
+	short   randval = (short)slapi_rand();
+	o_signature = c_signature ^ (randval % 32768);
+	if (!o_signature) {
+		randval = (short)slapi_rand();
+		o_signature = c_signature ^ (randval % 32768);
+	}
 
 	return o_signature;
 }
diff --git a/ldap/servers/plugins/pwdstorage/sha_pwd.c b/ldap/servers/plugins/pwdstorage/sha_pwd.c
index e54feab..8e9d60c 100644
--- a/ldap/servers/plugins/pwdstorage/sha_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/sha_pwd.c
@@ -54,6 +54,7 @@
 #include <sechash.h>
 
 #define SHA_SALT_LENGTH    8   /* number of bytes of data in salt */
+#define OLD_SALT_LENGTH    8
 #define NOT_FIRST_TIME (time_t)1 /* not the first logon */
 
 static char *hasherrmsg = "pw_cmp: %s userPassword \"%s\" is the wrong length or is not properly encoded BASE64\n";
@@ -82,7 +83,7 @@ sha_pw_cmp (const char *userpwd, const char *dbpwd, unsigned int shaLen )
     unsigned int secOID;
     char *schemeName;
     char *hashresult = NULL;
-                                                                                                                            
+
     /* Determine which algorithm we're using */
     switch (shaLen) {
         case SHA1_LENGTH:
@@ -111,8 +112,10 @@ sha_pw_cmp (const char *userpwd, const char *dbpwd, unsigned int shaLen )
      */
     hash_len = (strlen(dbpwd) * 3) / 4; /* includes the trailing = if any */
     if ( hash_len > sizeof(quick_dbhash) ) { /* get more space: */
-        dbhash = (char*) slapi_ch_malloc( hash_len );
+        dbhash = (char*) slapi_ch_calloc( hash_len, sizeof(char) );
         if ( dbhash == NULL ) goto loser;
+    } else {
+        memset( quick_dbhash, 0, sizeof(quick_dbhash) );
     }
     hashresult = PL_Base64Decode( dbpwd, 0, dbhash );
     if (NULL == hashresult) {
@@ -123,23 +126,25 @@ sha_pw_cmp (const char *userpwd, const char *dbpwd, unsigned int shaLen )
         salt.bv_len = SHA_SALT_LENGTH;
     } else if ( hash_len >= DS40B1_SALTED_SHA_LENGTH ) {
         salt.bv_val = (void*)dbhash;
-        salt.bv_len = 8;
+        salt.bv_len = OLD_SALT_LENGTH;
     } else { /* unsupported, invalid BASE64 (hash_len < 0), or similar */
                 slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, hasherrmsg, schemeName, dbpwd );
         goto loser;
     }
-                                                                                                                            
+
     /* hash the user's key */
+    memset( userhash, 0, sizeof(userhash) );
     if ( sha_salted_hash( userhash, userpwd, &salt, secOID ) != SECSuccess ) {
                 slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "sha_pw_cmp: sha_salted_hash() failed\n");
         goto loser;
     }
-                                                                                                                            
+
     /* the proof is in the comparison... */
     result = ( hash_len >= shaLen ) ?
-        ( memcmp( userhash, dbhash, shaLen )) : /* include salt */
-        ( memcmp( userhash, dbhash + 8, hash_len - 8 )); /* exclude salt */
-                                                                                                                            
+        ( memcmp( userhash, dbhash, shaLen ) ) : /* include salt */
+        ( memcmp( userhash, dbhash + OLD_SALT_LENGTH,
+                  hash_len - OLD_SALT_LENGTH ) ); /* exclude salt */
+
     loser:
     if ( dbhash && dbhash != quick_dbhash ) slapi_ch_free_string( &dbhash );
     return result;
@@ -153,7 +158,8 @@ sha_pw_enc( const char *pwd, unsigned int shaLen )
     char *schemeName;
     unsigned int schemeNameLen;
     unsigned int secOID;
-                                                                                                                            
+    size_t enclen;
+
     /* Determine which algorithm we're using */
     switch (shaLen) {
         case SHA1_LENGTH:
@@ -182,19 +188,20 @@ sha_pw_enc( const char *pwd, unsigned int shaLen )
     }
 
     /* hash the user's key */
+    memset( hash, 0, sizeof(hash) );
     if ( sha_salted_hash( hash, pwd, NULL, secOID ) != SECSuccess ) {
         return( NULL );
     }
-                                                                                                                            
-    if (( enc = slapi_ch_malloc( 3 + schemeNameLen +
-        LDIF_BASE64_LEN( shaLen ))) == NULL ) {
+
+    enclen = 3 + schemeNameLen + LDIF_BASE64_LEN( shaLen );
+    if (( enc = slapi_ch_calloc( enclen, sizeof(char) )) == NULL ) {
         return( NULL );
     }
-                                                                                                                            
+
     sprintf( enc, "%c%s%c", PWD_HASH_PREFIX_START, schemeName,
         PWD_HASH_PREFIX_END );
     (void)PL_Base64Encode( hash, shaLen, enc + 2 + schemeNameLen );
-                                                                                                                            
+
     return( enc );
 }
  
diff --git a/ldap/servers/plugins/pwdstorage/ssha_pwd.c b/ldap/servers/plugins/pwdstorage/ssha_pwd.c
index 14b8d44..6f09d5e 100644
--- a/ldap/servers/plugins/pwdstorage/ssha_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/ssha_pwd.c
@@ -131,10 +131,11 @@ salted_sha_pw_enc( const char *pwd, unsigned int shaLen )
     char *salt = hash + shaLen;
     struct berval saltval;
     char *enc;
+    size_t encsize;
     char *schemeName;
     unsigned int schemeNameLen;
     unsigned int secOID;
-                                                                                                                            
+
     /* Determine which algorithm we're using */
     switch (shaLen) {
         case SHA1_LENGTH:
@@ -161,31 +162,30 @@ salted_sha_pw_enc( const char *pwd, unsigned int shaLen )
             /* An unknown shaLen was passed in.  We shouldn't get here. */
             return( NULL );
     }
-                                                                                                                            
+
+    memset(hash, 0, sizeof(hash));
     saltval.bv_val = (void*)salt;
     saltval.bv_len = SHA_SALT_LENGTH;
-                                                                                                                            
+
     /* generate a new random salt */
-        /* Note: the uninitialized salt array provides a little extra entropy
-         * to the random array generation, but it is not really needed since
-         * PK11_GenerateRandom takes care of seeding. In any case, it doesn't
-         * hurt. */
-        ssha_rand_array( salt, SHA_SALT_LENGTH );
-                                                                                                                            
+    ssha_rand_array( salt, SHA_SALT_LENGTH );
+
     /* hash the user's key */
     if ( sha_salted_hash( hash, pwd, &saltval, secOID ) != SECSuccess ) {
         return( NULL );
     }
-                                                                                                                            
-    if (( enc = slapi_ch_malloc( 3 + schemeNameLen +
-        LDIF_BASE64_LEN(shaLen + SHA_SALT_LENGTH))) == NULL ) {
+
+    encsize = 3 + schemeNameLen +
+        LDIF_BASE64_LEN(shaLen + SHA_SALT_LENGTH);
+    if ( ( enc = slapi_ch_calloc( encsize, sizeof(char) ) ) == NULL ) {
         return( NULL );
     }
-                                                                                                                            
+
     sprintf( enc, "%c%s%c", PWD_HASH_PREFIX_START, schemeName,
         PWD_HASH_PREFIX_END );
     (void)PL_Base64Encode( hash, (shaLen + SHA_SALT_LENGTH), enc + 2 + schemeNameLen );
-                                                                                                                            
+    PR_ASSERT(0 == enc[encsize-1]); /* must be null terminated */
+
     return( enc );
 }
 
diff --git a/ldap/servers/plugins/syntaxes/bin.c b/ldap/servers/plugins/syntaxes/bin.c
index b7be0d1..2d0b6f8 100644
--- a/ldap/servers/plugins/syntaxes/bin.c
+++ b/ldap/servers/plugins/syntaxes/bin.c
@@ -165,8 +165,10 @@ bin_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
 	int	i;
 
 	for ( i = 0; bvals[i] != NULL; i++ ) {
-        if ( slapi_value_get_length(bvals[i]) == bvfilter->bv_len &&
-            0 == memcmp( slapi_value_get_string(bvals[i]), bvfilter->bv_val, bvfilter->bv_len ))
+        const struct berval *bv = slapi_value_get_berval(bvals[i]);
+
+        if ( ( bv->bv_len == bvfilter->bv_len ) &&
+             ( 0 == memcmp( bv->bv_val, bvfilter->bv_val, bvfilter->bv_len ) ) )
         {
 			if(retVal!=NULL)
 			{
diff --git a/ldap/servers/slapd/back-ldbm/id2entry.c b/ldap/servers/slapd/back-ldbm/id2entry.c
index e951e5e..4af281c 100644
--- a/ldap/servers/slapd/back-ldbm/id2entry.c
+++ b/ldap/servers/slapd/back-ldbm/id2entry.c
@@ -53,8 +53,8 @@ id2entry_add_ext( backend *be, struct backentry *e, back_txn *txn, int encrypt
     ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
     DB     *db = NULL;
     DB_TXN *db_txn = NULL;
-    DBT    data = {0};
-    DBT    key = {0};
+    DBT    data;
+    DBT    key;
     int    len, rc;
     char   temp_id[sizeof(ID)];
 	struct backentry *encrypted_entry = NULL;
@@ -70,6 +70,7 @@ id2entry_add_ext( backend *be, struct backentry *e, back_txn *txn, int encrypt
 
     id_internal_to_stored(e->ep_id,temp_id);
 
+    memset(&key, 0, sizeof(key));
     key.dptr = temp_id;
     key.dsize = sizeof(temp_id);
 
@@ -85,6 +86,7 @@ id2entry_add_ext( backend *be, struct backentry *e, back_txn *txn, int encrypt
 
 	{
 		Slapi_Entry *entry_to_use = encrypted_entry ? encrypted_entry->ep_entry : e->ep_entry;
+		memset(&data, 0, sizeof(data));
 		data.dptr = slapi_entry2str_with_options( entry_to_use, &len, SLAPI_DUMP_STATEINFO | SLAPI_DUMP_UNIQUEID);
 		data.dsize = len + 1;
 		/* If we had an encrypted entry, we no longer need it */
diff --git a/ldap/servers/slapd/back-ldbm/idl_new.c b/ldap/servers/slapd/back-ldbm/idl_new.c
index bf855f1..6edefd3 100644
--- a/ldap/servers/slapd/back-ldbm/idl_new.c
+++ b/ldap/servers/slapd/back-ldbm/idl_new.c
@@ -196,15 +196,15 @@ IDList * idl_new_fetch(
     int ret = 0;
     DBC *cursor = NULL;
     IDList *idl = NULL;
-    DBT key = {0};
-    DBT data = {0};
+    DBT key;
+    DBT data;
     ID id = 0;
     size_t count = 0;
 #ifdef DB_USE_BULK_FETCH
 	/* beware that a large buffer on the stack might cause a stack overflow on some platforms */
     char buffer[BULK_FETCH_BUFFER_SIZE]; 
     void *ptr;
-    DBT dataret = {0};
+    DBT dataret;
 #endif
 
     if (NEW_IDL_NOOP == *flag_err)
@@ -220,11 +220,13 @@ IDList * idl_new_fetch(
         cursor = NULL;
         goto error;
     }
+    memset(&data, 0, sizeof(data));
 #ifdef DB_USE_BULK_FETCH
     data.ulen = sizeof(buffer);
     data.size = sizeof(buffer);
     data.data = buffer;
     data.flags = DB_DBT_USERMEM;
+    memset(&dataret, 0, sizeof(dataret));
 #else
     data.ulen = sizeof(id);
     data.size = sizeof(id);
@@ -237,6 +239,7 @@ IDList * idl_new_fetch(
      * so we can just use the input key as a buffer.
      * This avoids memory management of the key.
      */
+    memset(&key, 0, sizeof(key));
     key.ulen = inkey->size;
     key.size = inkey->size;
     key.data = inkey->data;
@@ -367,7 +370,7 @@ int idl_new_insert_key(
 )
 {
     int ret = 0;
-    DBT data = {0};
+    DBT data;
 
 #if defined(DB_ALLIDS_ON_WRITE)
     DBC *cursor = NULL;
@@ -380,6 +383,7 @@ int idl_new_insert_key(
         cursor = NULL;
         goto error;
     }
+    memset(data, 0, sizeof(data)); /* bdb says data = {0} is not sufficient */
     data.ulen = sizeof(id);
     data.size = sizeof(id);
     data.flags = DB_DBT_USERMEM;
@@ -437,6 +441,7 @@ error:
         }
     }
 #else
+    memset(&data, 0, sizeof(data)); /* bdb says data = {0} is not sufficient */
     data.ulen = sizeof(id);
     data.size = sizeof(id);
     data.flags = DB_DBT_USERMEM;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
index bf8d843..a37c0ba 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
@@ -565,7 +565,7 @@ static void log_bytes(char* format_string, unsigned char *bytes, size_t length)
 static int
 attrcrypt_crypto_op(attrcrypt_private *priv, backend *be, struct attrinfo *ai, char *in_data, size_t in_size, char **out_data, size_t *out_size, int encrypt)
 {
-	int ret = 0;
+	int ret = -1;
 	SECStatus secret = 0;
 	PK11Context* sec_context = NULL;
 	SECItem iv_item = {0};
@@ -631,6 +631,7 @@ attrcrypt_crypto_op(attrcrypt_private *priv, backend *be, struct attrinfo *ai, c
 #endif
 		*out_size = output_buffer_size1 + output_buffer_size2;
 		*out_data = (char *)output_buffer;
+		ret = 0; /* success */
 	}
 error:
 	if (sec_context) {
@@ -639,6 +640,9 @@ error:
 	if (security_parameter) {
 		slapd_SECITEM_FreeItem(security_parameter, PR_TRUE);
 	}
+	if (ret) {
+		slapi_ch_free_string((char **)&output_buffer);
+	}
 	LDAPDebug(LDAP_DEBUG_TRACE,"<- attrcrypt_crypto_op\n", 0, 0, 0);
 	return ret;
 }
@@ -841,8 +845,6 @@ attrcrypt_encrypt_entry(backend *be, const struct backentry *in, struct backentr
 	struct backentry *new_entry = NULL;
 	char *type = NULL;
 	Slapi_Attr *attr = NULL;
-	Slapi_Value	**svals = NULL;
-	Slapi_Value **new_vals = NULL;
 
 	LDAPDebug(LDAP_DEBUG_TRACE,"-> attrcrypt_encrypt_entry\n", 0, 0, 0);
 	*out = NULL;
@@ -857,8 +859,9 @@ attrcrypt_encrypt_entry(backend *be, const struct backentry *in, struct backentr
 		ainfo_get(be, type, &ai);
 
 		if (ai && ai->ai_attrcrypt) {
-			svals = attr_get_present_values(attr);
+			Slapi_Value	**svals = attr_get_present_values(attr);
 			if (svals) {
+				Slapi_Value **new_vals = NULL;
 				/* If we find one, did we make the new entry yet ? */
 				if (NULL == new_entry) {
 					/* If not then make it now as a copy of the old entry */
@@ -871,7 +874,9 @@ attrcrypt_encrypt_entry(backend *be, const struct backentry *in, struct backentr
 					break;
 				}
 				/* DBDB does this call free the old value memory ? */
+				/* yes, DBDB, but it does not free new_vals - new_vals is copied */
 				slapi_entry_attr_replace_sv(new_entry->ep_entry, type, new_vals);
+				valuearray_free(&new_vals);
 			}
 		}
 	}
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index 279cef5..423164c 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -1205,7 +1205,8 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
             /* Decrypt in place */
             rc = attrcrypt_decrypt_entry(be, ep);
             if (rc) {
-                LDAPDebug(LDAP_DEBUG_ANY,"Failed to decrypt entry%s\n", ep->ep_entry->e_sdn , 0, 0);
+                LDAPDebug(LDAP_DEBUG_ANY,"Failed to decrypt entry [%s] : %d\n",
+                          slapi_sdn_get_dn(&ep->ep_entry->e_sdn), rc, 0);
             }
         }
 
diff --git a/ldap/servers/slapd/detach.c b/ldap/servers/slapd/detach.c
index dc8f988..51a369c 100644
--- a/ldap/servers/slapd/detach.c
+++ b/ldap/servers/slapd/detach.c
@@ -75,7 +75,7 @@
 #include <unistd.h>
 #endif /* USE_SYSCONF */
 
-void
+int
 detach( int slapd_exemode, int importexport_encrypt,
         int s_port, daemon_ports_t *ports_info )
 {
@@ -112,7 +112,7 @@ detach( int slapd_exemode, int importexport_encrypt,
 		/* call this right after the fork, but before closing stdin */
 		if (slapd_do_all_nss_ssl_init(slapd_exemode, importexport_encrypt,
 									  s_port, ports_info)) {
-			exit(1);
+			return 1;
 		}
 
 		workingdir = config_get_workingdir();
@@ -132,7 +132,7 @@ detach( int slapd_exemode, int importexport_encrypt,
 		} else {
 			/* calling config_set_workingdir to check for validity of directory, don't apply */
 			if (config_set_workingdir(CONFIG_WORKINGDIR_ATTRIBUTE, workingdir, errorbuf, 0) == LDAP_OPERATIONS_ERROR) {
-				exit(1);
+				return 1;
 			}
 			(void) chdir( workingdir );
 			slapi_ch_free_string(&workingdir);
@@ -140,7 +140,7 @@ detach( int slapd_exemode, int importexport_encrypt,
 
 		if ( (sd = open( "/dev/null", O_RDWR )) == -1 ) {
 			perror( "/dev/null" );
-			exit( 1 );
+			return 1;
 		}
 		(void) dup2( sd, 0 );
 		(void) dup2( sd, 1 );
@@ -160,12 +160,13 @@ detach( int slapd_exemode, int importexport_encrypt,
 	} else { /* not detaching - call nss/ssl init */
 		if (slapd_do_all_nss_ssl_init(slapd_exemode, importexport_encrypt,
 									  s_port, ports_info)) {
-			exit(1);
+			return 1;
 		}
 	}
 
 	(void) SIGNAL( SIGPIPE, SIG_IGN );
 #endif /* _WIN32 */
+	return 0;
 }
 
 
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index c611b9a..7e59511 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -94,6 +94,7 @@ union semun {
 #include "protect_db.h"
 #include "getopt_ext.h"
 #include "fe.h"
+#include <nss.h>
 
 #ifndef LDAP_DONT_USE_SMARTHEAP
 #include "smrtheap.h"
@@ -634,7 +635,6 @@ main( int argc, char **argv)
 	int return_value = 0;
 	slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
 	daemon_ports_t ports_info = {0};
-   	Slapi_Backend *be = NULL;
 #ifndef __LP64__ 
 #if defined(__hpux) && !defined(__ia64)
 	/* for static constructors */
@@ -923,7 +923,8 @@ main( int argc, char **argv)
         (slapd_exemode != SLAPD_EXEMODE_SLAPD)) {
         if (slapd_do_all_nss_ssl_init(slapd_exemode, importexport_encrypt,
                                       s_port, &ports_info)) {
-            return 1;
+            return_value = 1;
+            goto cleanup;
         }
     }
 
@@ -933,22 +934,34 @@ main( int argc, char **argv)
 	 */
 	switch ( slapd_exemode ) {
 	case SLAPD_EXEMODE_LDIF2DB:
-		return slapd_exemode_ldif2db();
+		return_value = slapd_exemode_ldif2db();
+		goto cleanup;
+		break;
 
 	case SLAPD_EXEMODE_DB2LDIF:
-		return slapd_exemode_db2ldif(argc,argv);
+		return_value = slapd_exemode_db2ldif(argc,argv);
+		goto cleanup;
+		break;
 
 	case SLAPD_EXEMODE_DB2INDEX:
-		return slapd_exemode_db2index();
+		return_value = slapd_exemode_db2index();
+		goto cleanup;
+		break;
 
 	case SLAPD_EXEMODE_ARCHIVE2DB:
-		return slapd_exemode_archive2db();
+		return_value = slapd_exemode_archive2db();
+		goto cleanup;
+		break;
 
 	case SLAPD_EXEMODE_DB2ARCHIVE:
-		return slapd_exemode_db2archive();
+		return_value = slapd_exemode_db2archive();
+		goto cleanup;
+		break;
 
 	case SLAPD_EXEMODE_DBTEST:
-		return slapd_exemode_dbtest();
+		return_value = slapd_exemode_dbtest();
+		goto cleanup;
+		break;
 		
 	case SLAPD_EXEMODE_REFERRAL:
 		/* check that all the necessary info was given, then go on */
@@ -961,21 +974,25 @@ main( int argc, char **argv)
 		break;
 
 	case SLAPD_EXEMODE_SUFFIX2INSTANCE:
-		return slapd_exemode_suffix2instance();
+		return_value = slapd_exemode_suffix2instance();
+		goto cleanup;
+		break;
 
 	case SLAPD_EXEMODE_UPGRADEDB:
-		return slapd_exemode_upgradedb();
+		return_value = slapd_exemode_upgradedb();
+		goto cleanup;
+		break;
 
 	case SLAPD_EXEMODE_DBVERIFY:
 		return_value = slapd_exemode_dbverify();
-		if (return_value == 0)
-			return return_value;
-		else
-			return 1;
+		goto cleanup;
+		break;
 
 	case SLAPD_EXEMODE_PRINTVERSION:
 		slapd_print_version(1);
-		exit(1);
+		return_value = 1;
+		goto cleanup;
+		break;
 	default:
 		{
 		char *rundir = config_get_rundir();
@@ -989,7 +1006,8 @@ main( int argc, char **argv)
 				slapdFrontendConfig->localuser, rundir, 0);
 			LDAPDebug(LDAP_DEBUG_ANY, "Shutting down.\n", 0, 0, 0);
 			slapi_ch_free_string(&rundir);
-			exit(1);
+			return_value = 1;
+			goto cleanup;
 		}
 		slapi_ch_free_string(&rundir);
 		break;
@@ -1003,8 +1021,11 @@ main( int argc, char **argv)
 	 * Have to detach after ssl_init - the user may be prompted for the PIN
 	 * on the terminal, so it must be open.
 	 */
-	detach(slapd_exemode, importexport_encrypt,
-           s_port, &ports_info);
+	if (detach(slapd_exemode, importexport_encrypt,
+			   s_port, &ports_info)) {
+		return_value = 1;
+		goto cleanup;
+	}
 
   /*
    * Now write our PID to the startup PID file.
@@ -1028,7 +1049,8 @@ main( int argc, char **argv)
  		LDAPDebug( LDAP_DEBUG_ANY, 
 				"Shutting down due to possible conflicts with other slapd processes\n",
 				0, 0, 0 );
-		exit(1);
+		return_value = 1;
+		goto cleanup;
 	}
 
 
@@ -1071,7 +1093,8 @@ main( int argc, char **argv)
 		{
 			LDAPDebug( LDAP_DEBUG_ANY, "Failed to init mapping tree\n",
 				0, 0, 0 );
-			exit(1);
+			return_value = 1;
+			goto cleanup;
 		}
 
 
@@ -1085,7 +1108,8 @@ main( int argc, char **argv)
 			LDAPDebug( LDAP_DEBUG_ANY,
 				"Fatal Error---Failed to initialize uniqueid generator; error = %d. "
 				"Exiting now.\n", rc, 0, 0 );
-			exit( 1 );
+			return_value = 1;
+			goto cleanup;
 		}
 
 		/* --ugaston: register the start-tls plugin */
@@ -1112,7 +1136,8 @@ main( int argc, char **argv)
 
 		plugin_startall(argc, argv, 1 /* Start Backends */, 1 /* Start Globals */); 
 		if (housekeeping_start((time_t)0, NULL) == NULL) {
-			exit (1);
+			return_value = 1;
+			goto cleanup;
 		}
 
 		eq_start();					/* must be done after plugins started */
@@ -1120,7 +1145,8 @@ main( int argc, char **argv)
 #ifdef HPUX10
 		/* HPUX linker voodoo */
 		if (collation_init == NULL) {
-		exit (1);
+			return_value = 1;
+			goto cleanup;
 		}
 		
 #endif /* HPUX */
@@ -1157,16 +1183,11 @@ main( int argc, char **argv)
                                 "Fatal Error---No ports specified. "
                                 "Exiting now.\n", 0, 0, 0 );
 			
-			exit(1);
+			return_value = 1;
+			goto cleanup;
 		}
 	}
 
-	{
-		Slapi_PBlock pb;
-		memset( &pb, '\0', sizeof(pb) );
-		pb.pb_backend = be;
-	}
-
 	if (slapd_exemode != SLAPD_EXEMODE_REFERRAL) {
 		/* else do this after seteuid() */
 		lite_entries_init();
@@ -1193,7 +1214,8 @@ main( int argc, char **argv)
 	 */
 	if ( search_register_reslimits() != SLAPI_RESLIMIT_STATUS_SUCCESS ||
 				daemon_register_reslimits() != SLAPI_RESLIMIT_STATUS_SUCCESS ) {
-		exit( 1 );
+		return_value = 1;
+		goto cleanup;
 	}
 
 	{
@@ -1206,15 +1228,19 @@ main( int argc, char **argv)
 	compute_terminate();
 	vattr_cleanup();
 	sasl_map_done();
+cleanup:
+	SSL_ShutdownServerSessionIDCache();
+	SSL_ClearSessionCache();
+	NSS_Shutdown();
 	PR_Cleanup();
 #ifdef _WIN32
 	/* Clean up the mutex used to interlock processes, before we exit */
 	remove_slapd_process();
 #endif
 #if ( defined( hpux ) || defined( irix ) || defined( aix ) || defined( OSF1 ))
-	exit( 0 );
+	exit( return_value );
 #else
-	return 0;
+	return return_value;
 #endif
 }
 
@@ -2055,7 +2081,7 @@ slapd_exemode_ldif2db()
                    "ERROR: Required argument -i <ldiffile> missing\n",
                    0, 0, 0 );
         usage( myname, extraname );
-        exit( 1 );
+        return 1;
     }
 
     /* this should be the first time to be called!  if the init order
@@ -2077,7 +2103,7 @@ slapd_exemode_ldif2db()
 				"ERROR: backend instances name [-n <name>] or "
 				"included suffix [-s <suffix>] need to be specified.\n",
 				0, 0, 0);
-			exit(1);
+			return 1;
 		}
 
 		if (instances) {
@@ -2088,7 +2114,7 @@ slapd_exemode_ldif2db()
 				LDAPDebug(LDAP_DEBUG_ANY, 
 					"ERROR 1: There is no backend instance to import to.\n",
 					0, 0, 0);
-				exit(1);
+				return 1;
 			} else if (counter > 1) {
 				int i;
 				LDAPDebug(LDAP_DEBUG_ANY, 
@@ -2097,7 +2123,7 @@ slapd_exemode_ldif2db()
 				for (i = 0; i < counter; i++)
 					LDAPDebug(LDAP_DEBUG_ANY, "     : %s\n",
 											  instances[i], 0, 0);
-        		exit(1);
+        		return 1;
 			} else {
 				LDAPDebug(LDAP_DEBUG_ANY, "Backend Instance: %s\n",
 					*instances, 0, 0);
@@ -2107,7 +2133,7 @@ slapd_exemode_ldif2db()
 			LDAPDebug(LDAP_DEBUG_ANY, 
 				"ERROR 2: There is no backend instance to import to.\n",
 				0, 0, 0);
-			exit(1);
+			return 1;
 		}
     }
 
@@ -2116,7 +2142,7 @@ slapd_exemode_ldif2db()
         LDAPDebug(LDAP_DEBUG_ANY, 
                   "ERROR: Could not find backend '%s'.\n",
                   cmd_line_instance_name, 0, 0);
-        exit(1);
+        return 1;
     }
 
     /* Make sure we aren't going to run slapd in 
@@ -2129,13 +2155,13 @@ slapd_exemode_ldif2db()
         LDAPDebug( LDAP_DEBUG_ANY, 
                    "Shutting down due to possible conflicts with other slapd processes\n",
                    0, 0, 0 );
-        exit(1);
+        return 1;
     }
     /* check for slapi v2 support */
     if (! SLAPI_PLUGIN_IS_V2(plugin)) {
         LDAPDebug(LDAP_DEBUG_ANY, "ERROR: %s is too old to do imports.\n",
                   plugin->plg_name, 0, 0);
-        exit(1);
+        return 1;
     }
 
     memset( &pb, '\0', sizeof(pb) );
@@ -2197,7 +2223,7 @@ slapd_exemode_db2ldif(int argc, char** argv)
 				"ERROR: backend instances name [-n <name>] or "
 				"included suffix [-s <suffix>] need to be specified.\n",
 				0, 0, 0);
-			exit(1);
+			return 1;
 		}
 
 		if (instances) {
@@ -2208,7 +2234,7 @@ slapd_exemode_db2ldif(int argc, char** argv)
 				LDAPDebug(LDAP_DEBUG_ANY, 
 					"ERROR 1: There is no backend instance to export from.\n",
 					0, 0, 0);
-				exit(1);
+				return 1;
 			} else {
 				LDAPDebug(LDAP_DEBUG_ANY, "Backend Instance(s): \n", 0, 0, 0);
 				for (ip = instances, counter = 0; ip && *ip; ip++, counter++) {
@@ -2220,7 +2246,7 @@ slapd_exemode_db2ldif(int argc, char** argv)
 			LDAPDebug(LDAP_DEBUG_ANY, 
 				"ERROR 2: There is no backend instance to export from.\n",
 				0, 0, 0);
-			exit(1);
+			return 1;
 		}
     }
 
@@ -2237,13 +2263,13 @@ slapd_exemode_db2ldif(int argc, char** argv)
 	        LDAPDebug(LDAP_DEBUG_ANY, 
 	                  "ERROR: Could not find backend '%s'.\n", 
 	                  *instp, 0, 0);
-	        exit(1);
+	        return 1;
 	    }
 	
 		if (plugin->plg_db2ldif == NULL) {
 			LDAPDebug(LDAP_DEBUG_ANY, "ERROR: no db2ldif function defined for "
 					  "backend %s - cannot export\n", *instp, 0, 0);
-			exit(1);
+			return 1;
 		}
 
 	    /* Make sure we aren't going to run slapd in 
@@ -2256,18 +2282,18 @@ slapd_exemode_db2ldif(int argc, char** argv)
 	                   "Shutting down due to possible conflicts "
 					   "with other slapd processes\n",
 	                   0, 0, 0 );
-	        exit(1);
+	        return 1;
 	    }
 	    if ( config_is_slapd_lite () &&
 			 !slapi_config_get_readonly () && is_slapd_running() ) {
 	        LDAPDebug( LDAP_DEBUG_ANY, "%s\n", LITE_BACKUP_ERR, 0, 0);
-	        exit ( 1 );
+	        return 1;
 	    }
 	
 	    if (! (SLAPI_PLUGIN_IS_V2(plugin))) {
 	        LDAPDebug(LDAP_DEBUG_ANY, "ERROR: %s is too old to do exports.\n",
 	                  plugin->plg_name, 0, 0);
-	        exit(1);
+	        return 1;
 	    }
 	
 	    memset( &pb, '\0', sizeof(pb) );
@@ -2405,7 +2431,7 @@ static int slapd_exemode_db2index()
                       "ERROR: backend instances name [-n <name>] or "
                       "included suffix [-s <suffix>] need to be specified.\n",
                       0, 0, 0);
-            exit(1);
+            return 1;
         }
 
         if (instances) {
@@ -2416,7 +2442,7 @@ static int slapd_exemode_db2index()
                 LDAPDebug(LDAP_DEBUG_ANY, 
                           "ERROR 1: There is no backend instance to import to.\n",
                           0, 0, 0);
-                exit(1);
+                return 1;
             } else if (counter > 1) {
                 int i;
                 LDAPDebug(LDAP_DEBUG_ANY, 
@@ -2425,7 +2451,7 @@ static int slapd_exemode_db2index()
                 for (i = 0; i < counter; i++)
                     LDAPDebug(LDAP_DEBUG_ANY, "     : %s\n",
                               instances[i], 0, 0);
-                exit(1);
+                return 1;
             } else {
                 LDAPDebug(LDAP_DEBUG_ANY, "Backend Instance: %s\n",
                           *instances, 0, 0);
@@ -2435,7 +2461,7 @@ static int slapd_exemode_db2index()
             LDAPDebug(LDAP_DEBUG_ANY, 
                       "ERROR 2: There is no backend instance to import to.\n",
                       0, 0, 0);
-            exit(1);
+            return 1;
         }
     }
 
@@ -2444,7 +2470,7 @@ static int slapd_exemode_db2index()
         LDAPDebug(LDAP_DEBUG_ANY, 
                   "ERROR: Could not find backend '%s'.\n",
                   cmd_line_instance_name, 0, 0);
-        exit(1);
+        return 1;
     }
 
     /* make sure nothing else is running */
@@ -2453,12 +2479,12 @@ static int slapd_exemode_db2index()
         LDAPDebug(LDAP_DEBUG_ANY,
                   "Shutting down due to possible conflicts with other "
                   "slapd processes.\n", 0, 0, 0);
-        exit(1);
+        return 1;
     }
 
     if ( db2index_attrs == NULL ) {
 	usage( myname, extraname );
-	exit( 1 );
+	return 1;
     }
     memset( &pb, '\0', sizeof(pb) );
     pb.pb_backend = NULL;
@@ -2488,18 +2514,18 @@ slapd_exemode_db2archive()
 		LDAPDebug(LDAP_DEBUG_ANY, 
 			"ERROR: Could not find the ldbm backend plugin.\n",
 			0, 0, 0);
-		exit(1);
+		return 1;
 	}
 	if (NULL == archive_name) {
 		LDAPDebug( LDAP_DEBUG_ANY,
 		    "ERROR: no archive directory supplied\n",
 		    0, 0, 0 );
-		exit( 1 );
+		return 1;
 	}
 
 	if ( config_is_slapd_lite ()  && !slapi_config_get_readonly ()  && is_slapd_running ()) {
 		LDAPDebug( LDAP_DEBUG_ANY, "%s\n", LITE_BACKUP_ERR, 0, 0);
-		exit ( 1 );
+		return 1;
 	}
 
 	/* Make sure we aren't going to run slapd in 
@@ -2511,11 +2537,11 @@ slapd_exemode_db2archive()
 	    LDAPDebug( LDAP_DEBUG_ANY, 
 		       "Shutting down due to possible conflicts with other slapd processes\n",
 		       0, 0, 0 );
-	    exit(1);
+	    return 1;
 	}
 	if (compute_init()) {
 		LDAPDebug(LDAP_DEBUG_ANY, "Initialization Failed 0 %d\n",return_value,0,0);
-		exit (1);
+		return 1;
 	}
 
 	memset( &pb, '\0', sizeof(pb) );
@@ -2543,13 +2569,13 @@ slapd_exemode_archive2db()
 		LDAPDebug(LDAP_DEBUG_ANY, 
 			"ERROR: Could not find the ldbm backend plugin.\n",
 			0, 0, 0);
-		exit(1);
+		return 1;
 	}
 	if (NULL == archive_name) {
 		LDAPDebug( LDAP_DEBUG_ANY,
 		    "ERROR: no archive directory supplied\n",
 		    0, 0, 0 );
-		exit( 1 );
+		return 1;
 	}
 	
 	/* Make sure we aren't going to run slapd in 
@@ -2561,11 +2587,11 @@ slapd_exemode_archive2db()
 	    LDAPDebug( LDAP_DEBUG_ANY, 
 		       "Shutting down due to possible conflicts with other slapd processes\n",
 		       0, 0, 0 );
-	    exit(1);
+	    return 1;
 	}
 	if (compute_init()) {
 		LDAPDebug(LDAP_DEBUG_ANY, "Initialization Failed 0 %d\n",return_value,0,0);
-		exit (1);
+		return 1;
 	}
 
 	memset( &pb, '\0', sizeof(pb) );
@@ -2598,7 +2624,7 @@ slapd_exemode_upgradedb()
                    "ERROR: Required argument -a <backup_dir> missing\n",
                    0, 0, 0 );
         usage( myname, extraname );
-        exit( 1 );
+        return 1;
     }
 
     /* this should be the first time to be called!  if the init order
@@ -2610,7 +2636,7 @@ slapd_exemode_upgradedb()
         LDAPDebug(LDAP_DEBUG_ANY, 
             "ERROR: Could not find the ldbm backend plugin.\n",
             0, 0, 0);
-        exit(1);
+        return 1;
     }
 
     /* Make sure we aren't going to run slapd in 
@@ -2621,13 +2647,13 @@ slapd_exemode_upgradedb()
         LDAPDebug( LDAP_DEBUG_ANY, 
                    "Shutting down due to possible conflicts with other slapd processes\n",
                    0, 0, 0 );
-        exit(1);
+        return 1;
     }
     /* check for slapi v2 support */
     if (! SLAPI_PLUGIN_IS_V2(backend_plugin)) {
         LDAPDebug(LDAP_DEBUG_ANY, "ERROR: %s is too old to do convert idl.\n",
                   backend_plugin->plg_name, 0, 0);
-        exit(1);
+        return 1;
     }
 
     memset( &pb, '\0', sizeof(pb) );
@@ -2674,14 +2700,14 @@ slapd_exemode_dbverify()
         LDAPDebug(LDAP_DEBUG_ANY, 
             "ERROR: Could not find the ldbm backend plugin.\n",
             0, 0, 0);
-        exit(1);
+        return 1;
     }
 
     /* check for slapi v2 support */
     if (! SLAPI_PLUGIN_IS_V2(backend_plugin)) {
         LDAPDebug(LDAP_DEBUG_ANY, "ERROR: %s is too old to do dbverify.\n",
                   backend_plugin->plg_name, 0, 0);
-        exit(1);
+        return 1;
     }
 
     memset( &pb, '\0', sizeof(pb) );
@@ -2715,7 +2741,7 @@ slapd_exemode_dbtest()
         LDAPDebug(LDAP_DEBUG_ANY, 
                   "dbtest: Required argument -n <instance name> missing\n", 0, 0, 0);
         usage( myname, extraname );
-        exit(1);
+        return 1;
     }
 
     mapping_tree_init();
@@ -2725,7 +2751,7 @@ slapd_exemode_dbtest()
         LDAPDebug(LDAP_DEBUG_ANY, 
                   "ERROR: Could not find backend '%s'.\n",
                   cmd_line_instance_name, 0, 0);
-        exit(1);
+        return 1;
     }
 
     /* Make sure we aren't going to run slapd in 
@@ -2738,7 +2764,7 @@ slapd_exemode_dbtest()
         LDAPDebug( LDAP_DEBUG_ANY, 
                    "Shutting down due to possible conflicts with other slapd processes\n",
                    0, 0, 0 );
-        exit(1);
+        return 1;
     }
 
     pb.pb_backend = NULL;
@@ -2943,9 +2969,13 @@ slapd_do_all_nss_ssl_init(int slapd_exemode, int importexport_encrypt,
 	 * other things even if we are not going to accept SSL connections.
 	 * We also need NSS for attribute encryption/decryption on import and export.
 	 */
-	int init_ssl = ( (slapd_exemode == SLAPD_EXEMODE_SLAPD) || importexport_encrypt) 
-        && config_get_security()
-        && (0 != s_port) && (s_port <= LDAP_PORT_MAX);
+	int init_ssl = config_get_security();
+
+	if (slapd_exemode == SLAPD_EXEMODE_SLAPD) {
+		init_ssl = init_ssl && (0 != s_port) && (s_port <= LDAP_PORT_MAX);
+	} else {
+		init_ssl = init_ssl && importexport_encrypt;
+	}
 	/* As of DS 6.1, always do a full initialization so that other
 	 * modules can assume NSS is available
 	 */
@@ -2953,7 +2983,7 @@ slapd_do_all_nss_ssl_init(int slapd_exemode, int importexport_encrypt,
                         (slapd_exemode != SLAPD_EXEMODE_REFERRAL) /* have config? */ )) {
         LDAPDebug(LDAP_DEBUG_ANY,
                   "ERROR: NSS Initialization Failed.\n", 0, 0, 0);
-        exit (1);
+        return 1;
 	}
 
 	if (slapd_exemode == SLAPD_EXEMODE_SLAPD) {
@@ -2963,7 +2993,7 @@ slapd_do_all_nss_ssl_init(int slapd_exemode, int importexport_encrypt,
 	if ( init_ssl && ( 0 != slapd_ssl_init())) {
 		LDAPDebug(LDAP_DEBUG_ANY,
                   "ERROR: SSL Initialization Failed.\n", 0, 0, 0 );
-		exit( 1 );
+		return 1;
 	}
 
 	if ((slapd_exemode == SLAPD_EXEMODE_SLAPD) ||
@@ -2974,7 +3004,7 @@ slapd_do_all_nss_ssl_init(int slapd_exemode, int importexport_encrypt,
 				if ( 0 != slapd_ssl_init2(sock, 0) ) {
 					LDAPDebug(LDAP_DEBUG_ANY,
                               "ERROR: SSL Initialization phase 2 Failed.\n", 0, 0, 0 );
-					exit( 1 );
+					return 1;
 				}
 			}
 		}
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
index c682597..479909a 100644
--- a/ldap/servers/slapd/mapping_tree.c
+++ b/ldap/servers/slapd/mapping_tree.c
@@ -556,11 +556,10 @@ get_backends_from_attr(Slapi_Attr *attr, backend ***be_list, char ***be_names,
 
 /* 
  * Description:
- * Release the memory allocated by the routine above.
- * Call this when the backend not put into structure and need to cleanup these tmp allocations
+ * Free the data allocated for mapping tree node arrays
  */
 static void
-free_get_backends_from_attr(backend ***be_list, char ***be_names,
+free_mapping_tree_node_arrays(backend ***be_list, char ***be_names,
     int ** be_states, int *be_list_count)
 {
     int i;
@@ -671,7 +670,7 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep )
 
             if (get_backends_from_attr(attr, &be_list, &be_names, &be_states,
                                        &be_list_count, &be_list_size, NULL)) {
-                free_get_backends_from_attr(&be_list, &be_names, &be_states, &be_list_count);
+                free_mapping_tree_node_arrays(&be_list, &be_names, &be_states, &be_list_count);
                 slapi_sdn_free(&subtree);
                 return lderr;
             }
@@ -776,7 +775,7 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep )
         "ERROR: node %s must define a backend\n",
         slapi_entry_get_dn(entry), 0, 0);
         slapi_sdn_free(&subtree);
-        free_get_backends_from_attr(&be_list, &be_names, &be_states, &be_list_count);
+        free_mapping_tree_node_arrays(&be_list, &be_names, &be_states, &be_list_count);
         return lderr;
     }
     if (((state == MTN_REFERRAL) || (state == MTN_REFERRAL_ON_UPDATE))
@@ -786,7 +785,7 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep )
         "ERROR: node %s must define referrals to be in referral state\n",
         slapi_entry_get_dn(entry), 0, 0);
         slapi_sdn_free(&subtree);
-        free_get_backends_from_attr(&be_list, &be_names, &be_states, &be_list_count);
+        free_mapping_tree_node_arrays(&be_list, &be_names, &be_states, &be_list_count);
         return lderr;
     }
 
@@ -803,7 +802,7 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep )
                 slapi_sdn_free(&subtree);
             slapi_ch_free((void **) &plugin_funct);
             slapi_ch_free((void **) &plugin_lib);
-            free_get_backends_from_attr(&be_list, &be_names, &be_states, &be_list_count);
+            free_mapping_tree_node_arrays(&be_list, &be_names, &be_states, &be_list_count);
             return lderr;
         }
     }
@@ -822,7 +821,7 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep )
         slapi_sdn_free(&subtree);
         slapi_ch_free((void **) &plugin_funct);
         slapi_ch_free((void **) &plugin_lib);
-        free_get_backends_from_attr(&be_list, &be_names, &be_states, &be_list_count);
+        free_mapping_tree_node_arrays(&be_list, &be_names, &be_states, &be_list_count);
         return lderr;
     }
         
@@ -1119,7 +1118,7 @@ int mapping_tree_entry_modify_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefor
             else if (get_backends_from_attr(attr, &backends, &be_names,
                          &be_states, &be_list_count, &be_list_size, node))
             {
-                free_get_backends_from_attr(&backends, &be_names, &be_states, &be_list_count);
+                free_mapping_tree_node_arrays(&backends, &be_names, &be_states, &be_list_count);
                 slapi_sdn_free(&subtree);
                 *returncode = LDAP_UNWILLING_TO_PERFORM;
                 return SLAPI_DSE_CALLBACK_ERROR;
@@ -1132,11 +1131,13 @@ int mapping_tree_entry_modify_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefor
                 PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "mapping tree entry need at least one nsslapd-backend\n");
                 *returncode = LDAP_UNWILLING_TO_PERFORM;
                 mtn_unlock();
-                free_get_backends_from_attr(&backends, &be_names, &be_states, &be_list_count);
+                free_mapping_tree_node_arrays(&backends, &be_names, &be_states, &be_list_count);
                 slapi_sdn_free(&subtree);
                 return SLAPI_DSE_CALLBACK_ERROR;
             }
 
+            /* free any old data */
+            free_mapping_tree_node_arrays(&node->mtn_be, &node->mtn_backend_names, &node->mtn_be_states, &node->mtn_be_count);
             node->mtn_be_states = be_states;
             node->mtn_be = backends;
             node->mtn_backend_names = be_names;
@@ -1642,7 +1643,7 @@ mapping_tree_init()
 }
 
 static void
-mtn_free_node (mapping_tree_node **node)
+mtn_free_node  (mapping_tree_node **node)
 {
     mapping_tree_node *child = (*node)->mtn_children;
 
@@ -1668,16 +1669,13 @@ mtn_free_node (mapping_tree_node **node)
 
     if ((*node)->mtn_be_count > 0)
     {
-        if ((*node)->mtn_be)
-            slapi_ch_free((void **) &((*node)->mtn_be));
-    
-        if ((*node)->mtn_backend_names)
-            slapi_ch_free((void **) &((*node)->mtn_backend_names));
-
-        if ((*node)->mtn_be_states)
-            slapi_ch_free((void **) &((*node)->mtn_be_states));
+        free_mapping_tree_node_arrays(&((*node)->mtn_be), &((*node)->mtn_backend_names),
+                                      &((*node)->mtn_be_states), &((*node)->mtn_be_count)); 
     }
 
+    slapi_ch_free_string(&((*node)->mtn_dstr_plg_lib));
+    slapi_ch_free_string(&((*node)->mtn_dstr_plg_name));
+
     slapi_ch_free ((void**) node);
 }
 
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index afcdb0b..f530d99 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -517,8 +517,8 @@ void do_delete( Slapi_PBlock *pb );
 /*
  * detach.c
  */
-void detach( int slapd_exemode, int importexport_encrypt,
-             int s_port, daemon_ports_t *ports_info );
+int detach( int slapd_exemode, int importexport_encrypt,
+			int s_port, daemon_ports_t *ports_info );
 #ifndef _WIN32
 void close_all_files( void );
 #endif
diff --git a/ldap/servers/slapd/sasl_map.c b/ldap/servers/slapd/sasl_map.c
index 383f045..08a6497 100644
--- a/ldap/servers/slapd/sasl_map.c
+++ b/ldap/servers/slapd/sasl_map.c
@@ -438,6 +438,11 @@ int sasl_map_done()
 	sasl_map_private *priv = sasl_map_get_global_priv();
 	sasl_map_data *dp = NULL;
 
+	/* there is no sasl map in referral mode */
+	if (!priv || !priv->lock || !priv->map_data_list) {
+		return 0;
+	}
+
 	/* Free the map list */
 	PR_Lock(priv->lock);
 	dp = priv->map_data_list;
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
index 5b10799..0866dc7 100644
--- a/ldap/servers/slapd/ssl.c
+++ b/ldap/servers/slapd/ssl.c
@@ -278,7 +278,7 @@ slapd_SSL_error(char *fmt, ...)
     va_list args;
     va_start(args, fmt);
     slapd_SSL_report(LOG_FAILURE, fmt, args);
-    exit(1);
+    va_end(args);
 }
 
 void
@@ -620,6 +620,7 @@ slapd_ssl_init() {
 		     (val ? "found" : "not found"));
       slapi_ch_free((void **) &val);
       slapi_ch_free((void **) &ciphers);
+      freeConfigEntry( &entry );
       return -1;
     }
 
@@ -627,6 +628,7 @@ slapd_ssl_init() {
     slapi_ch_free((void **) &val);
 
     if (svrcore_setup()) {
+	freeConfigEntry( &entry );
 	return -1;
     }
 
@@ -669,6 +671,7 @@ slapd_ssl_init() {
 				       SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", 
 				       errorCode, slapd_pr_strerror(errorCode));
       			freeChildren(family_list);
+      			freeConfigEntry( &entry );
       			return -1;
 		}
 
@@ -680,6 +683,7 @@ slapd_ssl_init() {
 				       SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
 				       errorCode, slapd_pr_strerror(errorCode));
       			freeChildren(family_list);
+      			freeConfigEntry( &entry );
       			return -1;
     		}
     		/* authenticate */
@@ -690,6 +694,7 @@ slapd_ssl_init() {
 				       SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
 				       errorCode, slapd_pr_strerror(errorCode));
       			freeChildren(family_list);
+      			freeConfigEntry( &entry );
       			return -1;
     		}
     	}
-- 
1.5.5.6

