[Fedora-directory-commits] ldapserver/ldap/servers/slapd/back-ldbm dblayer.c, 1.8, 1.9
Noriko Hosoi (nhosoi)
fedora-directory-commits at redhat.com
Tue Jan 10 23:53:16 UTC 2006
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv4197/back-ldbm
Modified Files:
dblayer.c
Log Message:
[174776] Multiple restores from a non-existant directory could wipe out database
If the specified backup dir does not exist, does not contain necessary files
(including the directory is not accessible), is not a directory, or is
identical to the path to the db dir, issues an error and stops restoring before
wiping out the database.
Index: dblayer.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/dblayer.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- dblayer.c 25 Apr 2005 16:24:23 -0000 1.8
+++ dblayer.c 10 Jan 2006 23:53:08 -0000 1.9
@@ -799,16 +799,12 @@
#if defined ( hpux )
{
struct pst_static pst;
- struct pst_dynamic pst_dyn;
int rval = pstat_getstatic(&pst, sizeof(pst), (size_t)1, 0);
if (rval < 0) /* pstat_getstatic failed */
return;
*pagesize = pst.page_size;
*pages = pst.physical_memory;
*availpages = dblayer_getvirtualmemsize() / *pagesize;
- rval = pstat_getdynamic(&pst_dyn, sizeof(pst_dyn), (size_t)1, 0);
- if (rval < 0) /* pstat_getdynamic failed */
- return;
if (procpages)
{
#define BURST (size_t)32 /* get BURST proc info at one time... */
@@ -2386,6 +2382,7 @@
priv->dblayer_env = NULL; /* pEnv is now garbage */
+#if 0 /* DBDB do NOT remove the environment: bad, bad idea */
if (return_value == 0) {
DB_ENV *env = 0;
return_value = db_env_create(&env, 0);
@@ -2397,9 +2394,7 @@
if (return_value == 0) {
char *home_dir = dblayer_get_home_dir(li, NULL);
if (home_dir)
- /* DBDB do NOT remove the environment: bad, bad idea
- * return_value = env->remove(env, home_dir, 0);
- */
+ return_value = env->remove(env, home_dir, 0);
if (0 == return_value
&& !((DBLAYER_ARCHIVE_MODE|DBLAYER_EXPORT_MODE) & dbmode)
&& !priv->dblayer_bad_stuff_happened) {
@@ -2415,6 +2410,7 @@
}
}
}
+#endif
return return_value;
}
@@ -4451,7 +4447,7 @@
int *cnt,
int instance_dir_flag,
int indexonly,
- int resetlsns)
+ int resetlsns)
{
dblayer_private *priv = NULL;
char *new_src_dir = NULL;
@@ -4593,14 +4589,14 @@
}
/* copy filename1 to filename2 */
- /* If the file is a database file, and resetlsns is set, then we need to do a key by key copy */
- if (strcmp(LDBM_FILENAME_SUFFIX, last_four_chars(filename1)) == 0 && resetlsns) {
- return_value = dblayer_copy_file_resetlsns(src_dir, filename1, filename2,
+ /* If the file is a database file, and resetlsns is set, then we need to do a key by key copy */
+ if (strcmp(LDBM_FILENAME_SUFFIX, last_four_chars(filename1)) == 0 && resetlsns) {
+ return_value = dblayer_copy_file_resetlsns(src_dir, filename1, filename2,
0, priv);
- } else {
- return_value = dblayer_copyfile(filename1, filename2,
+ } else {
+ return_value = dblayer_copyfile(filename1, filename2,
0, priv->dblayer_file_mode);
- }
+ }
slapi_ch_free((void**)&filename1);
slapi_ch_free((void**)&filename2);
if (0 > return_value)
@@ -4751,11 +4747,13 @@
/* compare: make sure everything in list A is still in list B */
ok = 1;
- for (listi = listA; *listi && ok; listi++) {
+ for (listi = listA; listi && *listi && ok; listi++) {
int found = 0;
- for (listj = listB; *listj && !found; listj++) {
- if (strcmp(*listi, *listj) == 0)
+ for (listj = listB; listj && *listj && !found; listj++) {
+ if (strcmp(*listi, *listj) == 0) {
found = 1;
+ break;
+ }
}
if (! found) {
ok = 0; /* missing log: start over */
@@ -4775,7 +4773,7 @@
}
if (ok) {
- size_t p1len, p2len;
+ size_t p1len, p2len;
char **listptr;
prefix = NULL;
@@ -4786,12 +4784,12 @@
prefix = home_dir;
}
/* log files have the same filename len(100 is a safety net:) */
- p1len = strlen(prefix) + strlen(*listB) + 100;
+ p1len = strlen(prefix) + strlen(*listB) + 100;
pathname1 = (char *)slapi_ch_malloc(p1len);
- p2len = strlen(dest_dir) + strlen(*listB) + 100;
+ p2len = strlen(dest_dir) + strlen(*listB) + 100;
pathname2 = (char *)slapi_ch_malloc(p2len);
/* We copy those over */
- for (listptr = listB; (*listptr) && ok; ++listptr) {
+ for (listptr = listB; listptr && *listptr && ok; ++listptr) {
PR_snprintf(pathname1, p1len, "%s/%s", prefix, *listptr);
PR_snprintf(pathname2, p2len, "%s/%s", dest_dir, *listptr);
LDAPDebug(LDAP_DEBUG_ANY, "Backing up file %d (%s)\n",
@@ -5172,8 +5170,9 @@
int dbmode;
int action = 0;
char *home_dir = NULL;
- char *real_src_dir = NULL;
- int frirestore = 0; /* Is a an FRI/single instance restore. 0 for no, 1 for yes */
+ char *real_src_dir = NULL;
+ int frirestore = 0; /* Is a an FRI/single instance restore. 0 for no, 1 for yes */
+ struct stat sbuf;
PR_ASSERT(NULL != li);
priv = (dblayer_private*)li->li_dblayer_private;
@@ -5188,7 +5187,7 @@
PR_Unlock(li->li_config_mutex);
home_dir = dblayer_get_home_dir(li, NULL);
-
+
if (NULL == home_dir)
{
LDAPDebug(LDAP_DEBUG_ANY,
@@ -5200,54 +5199,82 @@
/* If it is, we fail */
/* We check on the source staging area, no point in going further if it
* isn't there */
+ if (stat(src_dir, &sbuf) < 0) {
+ LDAPDebug(LDAP_DEBUG_ANY, "restore: backup directory %s does not "
+ "exist.\n", src_dir, 0, 0);
+ if (task) {
+ slapi_task_log_notice(task,
+ "Backup directory %s does not exist.\n", src_dir);
+ }
+ return LDAP_UNWILLING_TO_PERFORM;
+ } else if (!S_ISDIR(sbuf.st_mode)) {
+ LDAPDebug(LDAP_DEBUG_ANY, "restore: backup directory %s is not "
+ "a directory.\n", src_dir, 0, 0);
+ if (task) {
+ slapi_task_log_notice(task,
+ "Backup directory %s is not a directory.\n", src_dir);
+ }
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
if (!dbversion_exists(li, src_dir)) {
- LDAPDebug(LDAP_DEBUG_ANY, "restore: source directory %s does not "
+ LDAPDebug(LDAP_DEBUG_ANY, "restore: backup directory %s does not "
"contain a complete backup\n", src_dir, 0, 0);
-
-
if (task) {
- slapi_task_log_notice(task, "Source directory %s does not "
+ slapi_task_log_notice(task, "Backup directory %s does not "
"contain a complete backup", src_dir );
}
+ return LDAP_UNWILLING_TO_PERFORM;
}
- /* If this is a FRI restore, the bename will be non-NULL */
- if (bename != NULL)
- frirestore = 1;
-
- /*
- * Check if the target is a superset of the backup.
- * If not don't restore any db at all, otherwise
- * the target will be crippled.
- */
- dirhandle = PR_OpenDir(src_dir);
- if (NULL != dirhandle)
- {
- while ((direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))
- && direntry->name)
- {
+ /* If this is a FRI restore, the bename will be non-NULL */
+ if (bename != NULL)
+ frirestore = 1;
+
+ /*
+ * Check if the target is a superset of the backup.
+ * If not don't restore any db at all, otherwise
+ * the target will be crippled.
+ */
+ dirhandle = PR_OpenDir(src_dir);
+ if (NULL != dirhandle)
+ {
+ while ((direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))
+ && direntry->name)
+ {
PR_snprintf(filename1, MAXPATHLEN, "%s/%s", src_dir, direntry->name);
- if(!frirestore || strcmp(direntry->name,bename)==0)
- {
+ if(!frirestore || strcmp(direntry->name,bename)==0)
+ {
tmp_rval = PR_GetFileInfo(filename1, &info);
if (tmp_rval == PR_SUCCESS && PR_FILE_DIRECTORY == info.type) {
- inst = ldbm_instance_find_by_name(li, (char *)direntry->name);
- if ( inst == NULL)
- {
- LDAPDebug(LDAP_DEBUG_ANY,
- "ERROR: target server has no %s configured\n", direntry->name, 0, 0);
- if (task) {
- slapi_task_log_notice(task,
- "ERROR: target server has no %s configured\n", direntry->name);
- }
- PR_CloseDir(dirhandle);
- return LDAP_UNWILLING_TO_PERFORM;
- }
- }
- }
- }
- PR_CloseDir(dirhandle);
- }
+ inst = ldbm_instance_find_by_name(li, (char *)direntry->name);
+ if ( inst == NULL)
+ {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "ERROR: target server has no %s configured\n", direntry->name, 0, 0);
+ if (task) {
+ slapi_task_log_notice(task,
+ "ERROR: target server has no %s configured\n", direntry->name);
+ }
+ PR_CloseDir(dirhandle);
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
+
+ if (slapd_comp_path(src_dir, inst->inst_parent_dir_name)
+ == 0) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "ERROR: backup dir %s and target dir %s are identical\n", src_dir, inst->inst_parent_dir_name, 0);
+ if (task) {
+ slapi_task_log_notice(task,
+ "ERROR: backup dir %s and target dir %s are identical\n", src_dir, inst->inst_parent_dir_name);
+ }
+ PR_CloseDir(dirhandle);
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
+ }
+ }
+ }
+ PR_CloseDir(dirhandle);
+ }
/* We delete the existing database */
@@ -5256,20 +5283,20 @@
return return_value;
}
- if (frirestore) /*if we are restoring a single backend*/
- {
- char *new_src_dir = NULL;
- return_value = dblayer_fri_restore(home_dir,src_dir,priv,task,&new_src_dir,bename);
- if (return_value) {
- return return_value;
- }
- /* Now modify the src_dir to point to our recovery area and carry on as if nothing had happened... */
- real_src_dir = new_src_dir;
- } else
- {
- /* Otherwise use the src_dir from the caller */
- real_src_dir = src_dir;
- }
+ if (frirestore) /*if we are restoring a single backend*/
+ {
+ char *new_src_dir = NULL;
+ return_value = dblayer_fri_restore(home_dir,src_dir,priv,task,&new_src_dir,bename);
+ if (return_value) {
+ return return_value;
+ }
+ /* Now modify the src_dir to point to our recovery area and carry on as if nothing had happened... */
+ real_src_dir = new_src_dir;
+ } else
+ {
+ /* Otherwise use the src_dir from the caller */
+ real_src_dir = src_dir;
+ }
/* We copy the files over from the staging area */
/* We want to treat the logfiles specially: if there's
@@ -5300,14 +5327,14 @@
* directory is located.
*/
- inst = ldbm_instance_find_by_name(li, (char *)direntry->name);
- if (inst == NULL)
- continue;
+ inst = ldbm_instance_find_by_name(li, (char *)direntry->name);
+ if (inst == NULL)
+ continue;
restore_dir = inst->inst_parent_dir_name;
- /* If we're doing a partial restore, we need to reset the LSNs on the data files */
+ /* If we're doing a partial restore, we need to reset the LSNs on the data files */
if (dblayer_copy_directory(li, task, filename1,
- restore_dir, 1 /* restore */, &cnt, 0, 0, (bename) ? 1 : 0) == 0)
+ restore_dir, 1 /* restore */, &cnt, 0, 0, (bename) ? 1 : 0) == 0)
continue;
else
{
@@ -5418,7 +5445,7 @@
slapi_task_log_notice(task, "Failed to init database");
}
return_value = tmp_rval;
- goto error_out;
+ goto error_out;
}
if (0 == return_value) { /* only when the copyfile succeeded */
@@ -5443,21 +5470,21 @@
return_value = tmp_rval?tmp_rval:return_value;
error_out:
- /* Free the restore src dir, but only if we allocated it above */
- if (real_src_dir != src_dir) {
- /* If this was an FRI restore and the staging area exists, go ahead and remove it */
- if (frirestore && PR_Access(real_src_dir, PR_ACCESS_EXISTS) == PR_SUCCESS)
- {
- int ret1 = 0;
- LDAPDebug(LDAP_DEBUG_ANY, "dblayer_restore: Removing staging area %s.\n",real_src_dir, 0, 0);
- ret1 = ldbm_delete_dirs(real_src_dir);
- if (ret1)
- {
- LDAPDebug(LDAP_DEBUG_ANY, "dblayer_restore: Removal of staging area %s failed!\n", real_src_dir, 0, 0);
- }
- }
- slapi_ch_free((void**)&real_src_dir);
- }
+ /* Free the restore src dir, but only if we allocated it above */
+ if (real_src_dir != src_dir) {
+ /* If this was an FRI restore and the staging area exists, go ahead and remove it */
+ if (frirestore && PR_Access(real_src_dir, PR_ACCESS_EXISTS) == PR_SUCCESS)
+ {
+ int ret1 = 0;
+ LDAPDebug(LDAP_DEBUG_ANY, "dblayer_restore: Removing staging area %s.\n",real_src_dir, 0, 0);
+ ret1 = ldbm_delete_dirs(real_src_dir);
+ if (ret1)
+ {
+ LDAPDebug(LDAP_DEBUG_ANY, "dblayer_restore: Removal of staging area %s failed!\n", real_src_dir, 0, 0);
+ }
+ }
+ slapi_ch_free((void**)&real_src_dir);
+ }
return return_value;
}
More information about the Fedora-directory-commits
mailing list