From 12804d97cf4462cc0885a998d8299ef7c2f0257f Mon Sep 17 00:00:00 2001
From: Noriko Hosoi <nhosoi@redhat.com>
Date: Mon, 5 Aug 2013 16:46:41 -0700
Subject: [PATCH] Ticket #630 - The backend name provided to bak2db is not
 validated

Bug description: backend instance name was not validated correctly.
When a given backend instance name was not valid, the instance name
was ignored and the utility restored all instances, which was a default
behaviour of the restore -- bak2db.

Fix description: This patch adds the code to check the backend instance
name.  If there is no backend instance, the restore request is ignored.
In addition, it enhanced the back up path validation, as well.

There was another bug found in the restore/bak2db.  The backend instance
name is supposed to be case insensitive, but the case was not ignored.
The bug was fixed, too.

https://fedorahosted.org/389/ticket/630
---
 ldap/servers/slapd/back-ldbm/archive.c        | 50 ++++++++++++++++-----------
 ldap/servers/slapd/back-ldbm/dblayer.c        |  6 ++--
 ldap/servers/slapd/back-ldbm/dbversion.c      |  9 +++--
 ldap/servers/slapd/back-ldbm/import-threads.c |  2 +-
 ldap/servers/slapd/main.c                     |  6 ++--
 ldap/servers/slapd/task.c                     |  2 +-
 6 files changed, 42 insertions(+), 33 deletions(-)

diff --git a/ldap/servers/slapd/back-ldbm/archive.c b/ldap/servers/slapd/back-ldbm/archive.c
index f5fab1a..f8972f6 100644
--- a/ldap/servers/slapd/back-ldbm/archive.c
+++ b/ldap/servers/slapd/back-ldbm/archive.c
@@ -55,6 +55,10 @@ int ldbm_back_archive2ldbm( Slapi_PBlock *pb )
     int run_from_cmdline = 0;
     Slapi_Task *task;
     int is_old_to_new = 0;
+    ldbm_instance *inst = NULL;
+    char *dbversion = NULL;
+    char *dataversion = NULL;
+    int value = 0;
 
     slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
     slapi_pblock_get( pb, SLAPI_SEQ_VAL, &rawdirectory );
@@ -64,40 +68,46 @@ int ldbm_back_archive2ldbm( Slapi_PBlock *pb )
     li->li_flags = run_from_cmdline = (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE);
 
     if ( !rawdirectory || !*rawdirectory ) {
-        LDAPDebug( LDAP_DEBUG_ANY, "archive2db: no archive name\n",
-                   0, 0, 0 );
-        return( -1 );
+        LDAPDebug0Args(LDAP_DEBUG_ANY, "archive2db: no archive name\n");
+        return -1;
     }
 
     directory = rel2abspath(rawdirectory);
+    return_value = dbversion_read(li, directory, &dbversion, &dataversion);
+    if (return_value) {
+        if (ENOENT == return_value) {
+            LDAPDebug1Arg(LDAP_DEBUG_ANY, "archive2db: no back up \"%s\" exists.\n",
+                          directory);
+            return -1;
+        }
+        LDAPDebug1Arg(LDAP_DEBUG_ANY, "Warning: Unable to read dbversion file in %s\n",
+                      directory);
+    }
 
     /* check the current idl format vs backup DB version */
-    if (idl_get_idl_new())
-    {
-        char *dbversion = NULL;
-        char *dataversion = NULL;
-        int value = 0;
-
-        if (dbversion_read(li, directory, &dbversion, &dataversion) != 0)
-        {
-            LDAPDebug(LDAP_DEBUG_ANY, "Warning: Unable to read dbversion "
-                      "file in %s\n", directory, 0, 0);
-        }
+    if (idl_get_idl_new()) {
         value = lookup_dbversion(dbversion, DBVERSION_TYPE);
-        if (value & DBVERSION_OLD_IDL)
-        {
+        if (value & DBVERSION_OLD_IDL) {
             is_old_to_new = 1;
         }
-        slapi_ch_free_string(&dbversion);
-        slapi_ch_free_string(&dataversion);
     }
+    slapi_ch_free_string(&dbversion);
+    slapi_ch_free_string(&dataversion);
 
     /* No ldbm be's exist until we process the config information. */
     if (run_from_cmdline) {
         mapping_tree_init();
         ldbm_config_load_dse_info(li);
-    } else {
-        ldbm_instance *inst;
+    } 
+    if (backendname) {
+        inst = ldbm_instance_find_by_name(li, backendname);
+        if (NULL == inst) {
+            LDAPDebug1Arg(LDAP_DEBUG_ANY, "archive2db: backend \"%s\" does not exist.\n",
+                          backendname);
+            return -1;
+        }
+    }
+    if (!run_from_cmdline) {
         Object *inst_obj, *inst_obj2;
 
         /* task does not support restore old idl onto new idl server */
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index cddd9ce..5b981b0 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -5526,7 +5526,7 @@ dblayer_delete_database_ex(struct ldbminfo *li, char *instance, char *cldir)
         ldbm_instance *inst = (ldbm_instance *)object_get_data(inst_obj);
 
         if (inst->inst_be->be_instance_info != NULL) {
-			if ((NULL != instance) && (strcmp(inst->inst_name,instance) != 0)) 
+			if ((NULL != instance) && (strcasecmp(inst->inst_name,instance) != 0)) 
 			{
 				LDAPDebug(LDAP_DEBUG_ANY,
 					"dblayer_delete_database: skipping instance %s\n",inst->inst_name , 0, 0);	
@@ -6638,7 +6638,7 @@ static int dblayer_fri_trim(char *fri_dir_path, char* bename)
 			tmp_rval = PR_GetFileInfo64(filename, &info);
 			if (tmp_rval == PR_SUCCESS && PR_FILE_DIRECTORY == info.type)
 			{
-				if(strcmp(direntry->name,bename)!=0)
+				if(strcasecmp(direntry->name,bename)!=0)
 				{
 					LDAPDebug(LDAP_DEBUG_ANY, "Removing file %s from staging area\n",
                          filename, 0, 0);
@@ -6834,7 +6834,7 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
         {
             PR_snprintf(filename1, sizeof(filename1), "%s/%s",
                                                       src_dir, direntry->name);
-            if(!frirestore || strcmp(direntry->name,bename)==0)
+            if(!frirestore || strcasecmp(direntry->name,bename)==0)
             {
                 tmp_rval = PR_GetFileInfo64(filename1, &info);
                 if (tmp_rval == PR_SUCCESS && PR_FILE_DIRECTORY == info.type) {
diff --git a/ldap/servers/slapd/back-ldbm/dbversion.c b/ldap/servers/slapd/back-ldbm/dbversion.c
index e4eee32..033e1e1 100644
--- a/ldap/servers/slapd/back-ldbm/dbversion.c
+++ b/ldap/servers/slapd/back-ldbm/dbversion.c
@@ -160,15 +160,14 @@ dbversion_read(struct ldbminfo *li, const char *directory,
 {
     char filename[ MAXPATHLEN*2 ];
     PRFileDesc *prfd;
-    int rc = -1;
     char * iter = NULL;
 
     if (!is_fullpath((char *)directory)) {
-        return rc;
+        return ENOENT;
     }
 
     if (NULL == ldbmversion) {
-        return rc;
+        return EINVAL;
     }
 
     mk_dbversion_fullpath(li, directory, filename);
@@ -178,6 +177,7 @@ dbversion_read(struct ldbminfo *li, const char *directory,
           NULL )
     {
         /* File missing... we are probably creating a new database. */
+        return ENOENT;
     }
     else
     {
@@ -200,9 +200,8 @@ dbversion_read(struct ldbminfo *li, const char *directory,
             }
         }
         (void)PR_Close( prfd );
-        rc= 0;
+    	return 0;
     }
-    return rc;
 }
 
 
diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c
index c0475c6..3a3aab8 100644
--- a/ldap/servers/slapd/back-ldbm/import-threads.c
+++ b/ldap/servers/slapd/back-ldbm/import-threads.c
@@ -3709,7 +3709,7 @@ dse_conf_verify_core(struct ldbminfo *li, char *src_dir, char *file_name, char *
 
         if (entry_filter != NULL) /* Single instance restoration */
         {
-            if (NULL == strstr(estr, entry_filter)) {
+            if (NULL == PL_strcasestr(estr, entry_filter)) {
                 slapi_ch_free_string(&estr);
                 continue;
             }
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index a17a2c5..f1812be 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -2634,7 +2634,7 @@ slapd_exemode_db2archive()
 	memset( &pb, '\0', sizeof(pb) );
 	pb.pb_backend = NULL;
 	pb.pb_plugin = backend_plugin;
-	pb.pb_instance_name = cmd_line_instance_name;
+	pb.pb_instance_name = NULL;
 	pb.pb_seq_val = archive_name;
 	pb.pb_task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE;
 #ifndef _WIN32
@@ -2647,7 +2647,7 @@ slapd_exemode_db2archive()
 static int
 slapd_exemode_archive2db()
 {
-    int return_value= 0;
+	int return_value= 0;
 	Slapi_PBlock pb;
 	struct slapdplugin *backend_plugin;
 	slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -2664,7 +2664,7 @@ slapd_exemode_archive2db()
 		    0, 0, 0 );
 		return 1;
 	}
-	
+
 	/* Make sure we aren't going to run slapd in 
 	 * a mode that is going to conflict with other
 	 * slapd processes that are currently running
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
index 5fc0b08..3ffd799 100644
--- a/ldap/servers/slapd/task.c
+++ b/ldap/servers/slapd/task.c
@@ -1567,7 +1567,7 @@ static int task_restore_add(Slapi_PBlock *pb, Slapi_Entry *e,
     slapi_ch_free((void **)&cookie);
     if (NULL == be || NULL == be->be_database->plg_archive2db) {
         LDAPDebug(LDAP_DEBUG_ANY,
-                  "ERROR: no db2archive function defined.\n", 0, 0, 0);
+                  "ERROR: no archive2db function defined.\n", 0, 0, 0);
         *returncode = LDAP_UNWILLING_TO_PERFORM;
         rv = SLAPI_DSE_CALLBACK_ERROR;
         goto out;
-- 
1.8.1.4

