From: bert hubert Date: Fri, 29 Jan 2016 10:41:57 +0000 (+0100) Subject: add pdnsutil edit-zone X-Git-Tag: dnsdist-1.0.0-alpha2~24^2~6 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c2e0881c3da77abc715918a189b064267d2e937d;p=pdns add pdnsutil edit-zone --- diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index 902ccb489..8ceb2f1f8 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -18,6 +18,8 @@ #include "signingpipe.hh" #include "dns_random.hh" #include +#include //termios, TCSANOW, ECHO, ICANON + #ifdef HAVE_LIBSODIUM #include #endif @@ -28,6 +30,7 @@ #include "ssqlite3.hh" #include "bind-dnssec.schema.sqlite3.sql.h" #endif +#include StatBag S; PacketCache PC; @@ -401,7 +404,7 @@ void rectifyAllZones(DNSSECKeeper &dk) cout<<"Rectified "<* suppliedrecords=0) { SOAData sd; if(!B.getSOAUncached(zone, sd)) { @@ -447,15 +450,23 @@ int checkZone(DNSSECKeeper &dk, UeberBackend &B, const DNSName& zone) bool hasNsAtApex = false; set tlsas, cnames, noncnames, glue, checkglue; - set records; + set recordcontents; map ttl; ostringstream content; pair::iterator,bool> ret; - sd.db->list(zone, sd.domain_id, false); + vector records; + if(!suppliedrecords) { + sd.db->list(zone, sd.domain_id, false); + while(sd.db->get(rr)) { + records.push_back(rr); + } + } + else + records=*suppliedrecords; - while(sd.db->get(rr)) { + for(auto rr : records) { // we modify this if(!rr.qtype.getCode()) continue; @@ -511,12 +522,12 @@ int checkZone(DNSSECKeeper &dk, UeberBackend &B, const DNSName& zone) content.str(""); content< pre, post; + char tmpnam[]="/tmp/pdnsutil-XXXXXX"; + int tmpfd=mkstemp(tmpnam); + if(tmpfd < 0) + unixDie("Making temporary filename in "+string(tmpnam)); + struct deleteme { + ~deleteme() { unlink(d_name.c_str()); } + deleteme(string name) : d_name(name) {} + string d_name; + } dm(tmpnam); + + bool first=true; + vector checkrr; + int gotoline=0; + string editor="editor"; + if(auto e=getenv("EDITOR")) // <3 + editor=e; + string cmdline; + editAgain:; + di.backend->list(zone, di.id); + pre.clear(); post.clear(); + DNSResourceRecord rr; + { + if(tmpfd < 0 && (tmpfd=open(tmpnam, O_WRONLY, 0600)) < 0) + unixDie("Error reopening temporary file "+string(tmpnam)); + string header("; Warning - all zone names in this file are ABSOLUTE!\n$ORIGIN .\n"); + if(write(tmpfd, header.c_str(), header.length()) < 0) + unixDie("Writing zone to temporary file"); + while(di.backend->get(rr)) { + DNSRecord dr(rr); + pre.push_back(dr); + ostringstream os; + os<getZoneRepresentation(true)< 0) + cmdline+="+"+std::to_string(gotoline)+" "; + cmdline += tmpnam; + if(system(cmdline.c_str()) < 0) { + unixDie("Editing file with: "+cmdline); + } + cmdline.clear(); + stat(tmpnam,&statafter); + if(first && statbefore.st_ctime == statafter.st_ctime) { + cout<<"No change to file"<, vector > grouped; + while(zpt.get(rr)) { + try { + DNSRecord dr(rr); + post.push_back(dr); + grouped[{dr.d_name,dr.d_type}].push_back(dr); + } + catch(std::exception& e) { + cerr<<"Problem "< diff; + set> changed; + set_difference(pre.cbegin(), pre.cend(), post.cbegin(), post.cend(), back_inserter(diff)); + for(const auto& d : diff) { + changed.insert({d.d_name,d.d_type}); + cout<<'-'<< d.d_name <<" "<getZoneRepresentation(true)<getZoneRepresentation(true)< vrr; + for(const DNSRecord& rr : grouped[c]) { + DNSResourceRecord drr(rr); + drr.domain_id = di.id; + vrr.push_back(drr); + } + di.backend->replaceRRSet(di.id, c.first, QType(c.second), vrr); + } + return 0; +} + + int loadZone(DNSName zone, const string& fname) { UeberBackend B; DomainInfo di; @@ -1615,6 +1802,7 @@ try cerr<<"delete-tsig-key NAME Delete TSIG key (warning! will not unmap key!)"< 2) { cerr<<"Syntax: pdnsutil list-keys [ZONE]"<