Commit b7e031d5 authored by Andreas Gustafsson's avatar Andreas Gustafsson
Browse files

435. [bug] dns_zone_dump() overwrote existing zone files

                        rather than writing to a temporary file and
                        renaming.  This could lead to empty or partial
                        zone files being left around in certain error
                        conditions involving the initial transfer of a
                        slave zone, interfering with subsequent server
                        startup. [RT #282]
parent c9f54e6d
435. [bug] dns_zone_dump() overwrote existing zone files
rather than writing to a temporary file and
renaming. This could lead to empty or partial
zone files being left around in certain error
conditions involving the initial transfer of a
slave zone, interfering with subsequent server
startup. [RT #282]
434. [func] New function isc_file_isabsolute().
433. [func] isc_base64_decodestring() now accepts newlines
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: masterdump.c,v 1.33 2000/08/16 22:33:32 gson Exp $ */
/* $Id: masterdump.c,v 1.34 2000/09/08 21:47:03 gson Exp $ */
#include <config.h>
......@@ -882,27 +882,68 @@ dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
{
FILE *f = NULL;
isc_result_t result;
char *tempname;
int tempnamelen;
result = isc_stdio_open(filename, "w", &f);
tempnamelen = strlen(filename) + 20;
tempname = isc_mem_get(mctx, tempnamelen);
if (tempname == NULL)
return (ISC_R_NOMEMORY);
result = isc_file_mktemplate(filename, tempname, tempnamelen);
if (result != ISC_R_SUCCESS)
goto cleanup;
result = isc_file_openunique(tempname, &f);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
"dumping master file: %s: open: %s", filename,
isc_result_totext(result));
return (ISC_R_UNEXPECTED);
"dumping master file: %s: open: %s",
tempname, isc_result_totext(result));
goto cleanup;
}
result = dns_master_dumptostream(mctx, db, version, style, f);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
"dumping master file: %s: %s",
tempname, isc_result_totext(result));
(void)isc_stdio_close(f);
(void)isc_file_remove(tempname);
goto cleanup;
}
result = isc_stdio_close(f);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
"dumping master file: %s: close: %s", filename,
isc_result_totext(result));
return (ISC_R_UNEXPECTED);
"dumping master file: %s: close: %s",
tempname, isc_result_totext(result));
(void)isc_file_remove(tempname);
goto cleanup;
}
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
"dumping master file: %s: close: %s",
tempname, isc_result_totext(result));
goto cleanup;
}
result = isc_file_rename(tempname, filename);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
"dumping master file: rename: %s: %s",
filename, isc_result_totext(result));
goto cleanup;
}
cleanup:
isc_mem_put(mctx, tempname, tempnamelen);
return (result);
}
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: zone.c,v 1.204 2000/09/08 00:07:44 explorer Exp $ */
/* $Id: zone.c,v 1.205 2000/09/08 21:47:01 gson Exp $ */
#include <config.h>
......@@ -1734,11 +1734,6 @@ static isc_result_t
zone_dump(dns_zone_t *zone) {
isc_result_t result;
dns_dbversion_t *version = NULL;
dns_db_t *db = NULL;
char *buf;
int buflen;
FILE *f = NULL;
int n;
/*
* 'zone' locked by caller.
......@@ -1747,47 +1742,19 @@ zone_dump(dns_zone_t *zone) {
REQUIRE(ISLOCKED(&zone->lock));
buflen = strlen(zone->dbname) + 20;
buf = isc_mem_get(zone->mctx, buflen);
if (buf == NULL)
return (ISC_R_NOMEMORY);
dns_db_currentversion(zone->db, &version);
result = isc_file_mktemplate(zone->dbname, buf, buflen);
if (result != ISC_R_SUCCESS)
goto cleanup;
result = dns_master_dump(zone->mctx, zone->db, version,
&dns_master_style_default,
zone->dbname);
dns_db_closeversion(zone->db, &version, ISC_FALSE);
result = isc_file_openunique(buf, &f);
if (result != ISC_R_SUCCESS)
goto cleanup;
return (result);
dns_db_attach(zone->db, &db);
dns_db_currentversion(db, &version);
result = dns_master_dumptostream(zone->mctx, db, version,
&dns_master_style_default, f);
dns_db_closeversion(db, &version, ISC_FALSE);
dns_db_detach(&db);
n = fflush(f);
if (n != 0 && result == ISC_R_SUCCESS)
result = ISC_R_UNEXPECTED;
n = ferror(f);
if (n != 0 && result == ISC_R_SUCCESS)
result = ISC_R_UNEXPECTED;
n = fclose(f);
if (n != 0 && result == ISC_R_SUCCESS)
result = ISC_R_UNEXPECTED;
if (result == ISC_R_SUCCESS) {
n = rename(buf, zone->dbname);
if (n == -1) {
(void)remove(buf);
result = ISC_R_UNEXPECTED;
} else {
zone->flags &= ~DNS_ZONEFLG_NEEDDUMP;
}
} else
(void)remove(buf);
cleanup:
isc_mem_put(zone->mctx, buf, buflen);
return (result);
zone->flags &= ~DNS_ZONEFLG_NEEDDUMP;
return (ISC_R_SUCCESS);
}
isc_result_t
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: file.h,v 1.10 2000/09/08 18:37:25 gson Exp $ */
/* $Id: file.h,v 1.11 2000/09/08 21:46:58 gson Exp $ */
#ifndef ISC_FILE_H
#define ISC_FILE_H 1
......@@ -159,6 +159,12 @@ isc_file_remove(const char *filename);
* Remove the file named by 'filename'.
*/
isc_result_t
isc_file_rename(const char *oldname, const char *newname);
/*
* Rename the file 'oldname' to 'newname'.
*/
isc_boolean_t
isc_file_isabsolute(const char *filename);
/*
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: file.c,v 1.21 2000/09/08 18:37:26 gson Exp $ */
/* $Id: file.c,v 1.22 2000/09/08 21:46:59 gson Exp $ */
#include <config.h>
......@@ -181,6 +181,17 @@ isc_file_remove(const char *filename) {
return (isc__errno2result(errno));
}
isc_result_t
isc_file_rename(const char *oldname, const char *newname) {
int r;
r = rename(oldname, newname);
if (r == 0)
return (ISC_R_SUCCESS);
else
return (isc__errno2result(errno));
}
isc_boolean_t
isc_file_isabsolute(const char *filename) {
return (ISC_TF(filename[0] == '/'));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment