From: Remi Gacogne Date: Thu, 31 Aug 2023 12:52:46 +0000 (+0200) Subject: ixfrutils: Set a strong umask before writing a zone file X-Git-Tag: rec-5.0.0-rc1~46^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a7aecb20d30c8593fea9bcee736ae05ace75138;p=thirdparty%2Fpdns.git ixfrutils: Set a strong umask before writing a zone file --- diff --git a/pdns/ixfrutils.cc b/pdns/ixfrutils.cc index 4c8e37fa6b..12b0a3e11b 100644 --- a/pdns/ixfrutils.cc +++ b/pdns/ixfrutils.cc @@ -23,6 +23,8 @@ #include #include #include +#include + #include "ixfrutils.hh" #include "sstuff.hh" #include "dnssecinfra.hh" @@ -127,32 +129,35 @@ void writeZoneToDisk(const records_t& records, const DNSName& zone, const std::s { DNSRecord soa; auto serial = getSerialFromRecords(records, soa); - string fname=directory +"/"+std::to_string(serial); - auto fp = std::unique_ptr(fopen((fname+".partial").c_str(), "w"), fclose); - if (!fp) { + string fname = directory + "/" + std::to_string(serial); + /* ensure that the partial zone file will only be accessible by the current user, not even + by other users in the same group, and certainly not by other users. */ + umask(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); + auto filePtr = std::unique_ptr(fopen((fname+".partial").c_str(), "w"), fclose); + if (!filePtr) { throw runtime_error("Unable to open file '"+fname+".partial' for writing: "+stringerror()); } records_t soarecord; soarecord.insert(soa); - if (fprintf(fp.get(), "$ORIGIN %s\n", zone.toString().c_str()) < 0) { + if (fprintf(filePtr.get(), "$ORIGIN %s\n", zone.toString().c_str()) < 0) { string error = "Error writing to zone file for " + zone.toLogString() + " in file " + fname + ".partial" + ": " + stringerror(); - fp.reset(); + filePtr.reset(); unlink((fname+".partial").c_str()); throw std::runtime_error(error); } try { - writeRecords(fp.get(), soarecord); - writeRecords(fp.get(), records); - writeRecords(fp.get(), soarecord); + writeRecords(filePtr.get(), soarecord); + writeRecords(filePtr.get(), records); + writeRecords(filePtr.get(), soarecord); } catch (runtime_error &e) { - fp.reset(); + filePtr.reset(); unlink((fname+".partial").c_str()); throw runtime_error("Error closing zone file for " + zone.toLogString() + " in file " + fname + ".partial" + ": " + e.what()); } - if (fclose(fp.release()) != 0) { + if (fclose(filePtr.release()) != 0) { string error = "Error closing zone file for " + zone.toLogString() + " in file " + fname + ".partial" + ": " + stringerror(); unlink((fname+".partial").c_str()); throw std::runtime_error(error);