Pullup for Andreas:
Log Message:
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]
This commit is contained in:
8
CHANGES
8
CHANGES
@@ -7,6 +7,14 @@
|
||||
not logged at a high enough logging level to be
|
||||
useful in diagnosing this situation. [RT #275]
|
||||
|
||||
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]
|
||||
|
||||
429. [bug] The space reserved for a TSIG record in a response
|
||||
was 2 bytes too short, leading to message
|
||||
generation failures.
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: masterdump.c,v 1.27.2.1 2000/08/15 00:29:48 gson Exp $ */
|
||||
/* $Id: masterdump.c,v 1.27.2.2 2000/09/11 19:27:47 explorer Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -859,26 +859,67 @@ 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 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: zone.c,v 1.152.2.10 2000/09/07 16:55:33 gson Exp $ */
|
||||
/* $Id: zone.c,v 1.152.2.11 2000/09/11 19:27:49 explorer Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -1498,58 +1498,25 @@ 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.
|
||||
*/
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
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 = 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_mktemplate(zone->dbname, buf, buflen);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
return (result);
|
||||
|
||||
result = isc_file_openunique(buf, &f);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
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 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: file.h,v 1.7 2000/06/22 21:57:32 tale Exp $ */
|
||||
/* $Id: file.h,v 1.7.2.1 2000/09/11 19:27:50 explorer 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'.
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX We should also have a isc_file_writeeopen() function
|
||||
* for safely open a file in a publicly writable directory
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: file.c,v 1.17 2000/06/22 21:58:35 tale Exp $ */
|
||||
/* $Id: file.c,v 1.17.2.1 2000/09/11 19:27:52 explorer Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -182,3 +182,14 @@ isc_file_remove(const char *filename) {
|
||||
else
|
||||
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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user