]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Pullup for Andreas:
authorMichael Graff <mgraff@isc.org>
Mon, 11 Sep 2000 19:27:52 +0000 (19:27 +0000)
committerMichael Graff <mgraff@isc.org>
Mon, 11 Sep 2000 19:27:52 +0000 (19:27 +0000)
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]

CHANGES
lib/dns/masterdump.c
lib/dns/zone.c
lib/isc/include/isc/file.h
lib/isc/unix/file.c

diff --git a/CHANGES b/CHANGES
index b781d729bcc427f5ca5abfac74ed909b34dd5327..0c34644b6254d4d335a4ec248c4428cb60183f88 100644 (file)
--- a/CHANGES
+++ b/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.
index 2971f14517785d36dde833d40a0f37c5ae5909e1..aac3bb7f6b391d30d01236224bdf8cc43e3dd53d 100644 (file)
@@ -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);
 }
index 6275573dd19df89f5b79131ec983a572e35b65c1..13e7b74f89bc9958eaa3b698235e7fb80dca4967 100644 (file)
@@ -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 = 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
index a367a69b9a8519607b4ed560a8062270ef8fb304..3b5caa2c2f6f514529509092625f249ed025b64e 100644 (file)
@@ -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
index 793b8a7f49b062d3859ca6f0d8ab579634cf199d..8facaa81bb37dbad234efd54d0c40245ca770379 100644 (file)
@@ -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));
+}