Browse Source

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.

Reviewed by Rich (Thank you!!)

https://fedorahosted.org/389/ticket/630
Noriko Hosoi 12 years ago
parent
commit
ad32c623e8

+ 30 - 20
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 */

+ 3 - 3
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) {

+ 16 - 13
ldap/servers/slapd/back-ldbm/dbversion.c

@@ -160,30 +160,34 @@ dbversion_read(struct ldbminfo *li, const char *directory,
 {
     char filename[ MAXPATHLEN*2 ];
     PRFileDesc *prfd;
-    int rc = -1;
     char * iter = NULL;
+    PRFileInfo64 fileinfo;
+    int rc;
 
     if (!is_fullpath((char *)directory)) {
-        return rc;
+        return ENOENT;
     }
 
     if (NULL == ldbmversion) {
-        return rc;
+        return EINVAL;
+    }
+
+    rc = PR_GetFileInfo64(directory, &fileinfo);
+    if ((rc != PR_SUCCESS) || (fileinfo.type != PR_FILE_DIRECTORY)) {
+        /* Directory does not exist or not a directory. */
+        return ENOENT;
     }
 
     mk_dbversion_fullpath(li, directory, filename);
     
     /* Open the file */
-    if (( prfd = PR_Open( filename, PR_RDONLY, SLAPD_DEFAULT_FILE_MODE  )) ==
-          NULL )
-    {
+    prfd = PR_Open(filename, PR_RDONLY, SLAPD_DEFAULT_FILE_MODE);
+    if (prfd == NULL) {
         /* File missing... we are probably creating a new database. */
-    }
-    else
-    {
+        return EACCES;
+    } else {
         char buf[LDBM_VERSION_MAXBUF];
-        PRInt32 nr = slapi_read_buffer( prfd, buf,
-                    (PRInt32)LDBM_VERSION_MAXBUF-1 );
+        PRInt32 nr = slapi_read_buffer(prfd, buf, (PRInt32)LDBM_VERSION_MAXBUF-1);
         if ( nr > 0 && nr != (PRInt32)LDBM_VERSION_MAXBUF-1 )
         {
             char *t;
@@ -200,9 +204,8 @@ dbversion_read(struct ldbminfo *li, const char *directory,
             }
         }
         (void)PR_Close( prfd );
-        rc= 0;
+        return 0;
     }
-    return rc;
 }
 
 

+ 1 - 1
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;
             }

+ 3 - 3
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

+ 1 - 1
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;