Package: release.debian.org Severity: normal Tags: stretch User: release.debian....@packages.debian.org Usertags: pu
Dear Release Managers, pdns/4.0.3-1+deb9u3 would fix two important and two not-high-prio security bugs: * #898255: CVE-2018-1046 in dnsreplay (pdns-tools) * #913163: CVE-2018-10851 (pdns) * #889798: MySQL queries with stored procedures fail * #911659: ldap, lua, opendbx backends don't actually find zones I've been in contact with security@ about the CVEs. debdiff below. The submitter for #889798 says the new package fixes their problem. Thanks, Chris diff -Nru pdns-4.0.3/debian/changelog pdns-4.0.3/debian/changelog --- pdns-4.0.3/debian/changelog 2017-11-27 22:02:24.000000000 +0000 +++ pdns-4.0.3/debian/changelog 2018-11-10 13:36:22.000000000 +0000 @@ -1,3 +1,13 @@ +pdns (4.0.3-1+deb9u3) stretch; urgency=medium + + * Fix (security) bugs, partially using upstream patches: + * CVE-2018-1046 in dnsreplay (Closes: #898255) + * CVE-2018-10851 (Closes: #913163) + * MySQL queries with stored procedures (Closes: #889798) + * ldap, lua, opendbx backend not finding domains (Closes: #911659) + + -- Christian Hofstaedtler <z...@debian.org> Sat, 10 Nov 2018 13:36:22 +0000 + pdns (4.0.3-1+deb9u2) stretch; urgency=medium * Add upstream patch fixing security issue: diff -Nru pdns-4.0.3/debian/patches/889798-auth-Always-bind-the-results-array-after-executing-a.patch pdns-4.0.3/debian/patches/889798-auth-Always-bind-the-results-array-after-executing-a.patch --- pdns-4.0.3/debian/patches/889798-auth-Always-bind-the-results-array-after-executing-a.patch 1970-01-01 00:00:00.000000000 +0000 +++ pdns-4.0.3/debian/patches/889798-auth-Always-bind-the-results-array-after-executing-a.patch 2018-11-10 13:36:22.000000000 +0000 @@ -0,0 +1,71 @@ +From 4fd90e75d47d6ec43d10c94ea260b08e50806442 Mon Sep 17 00:00:00 2001 +From: Remi Gacogne <remi.gaco...@powerdns.com> +Date: Tue, 2 Jan 2018 17:03:47 +0100 +Subject: [PATCH] auth: Always bind the results array after executing a + statement + +We will reuse the same array most of the time, but it turns out that +calling mysql_stmt_next_result() followed by mysql_stmt_store_result() +invalidates the existing binding (the first one sets stmt->bind_result_done +to false, causing the second to reset the existing binding). +--- + modules/gmysqlbackend/smysql.cc | 31 +++++++++++++++++++------------ + 1 file changed, 19 insertions(+), 12 deletions(-) + +diff --git a/modules/gmysqlbackend/smysql.cc b/modules/gmysqlbackend/smysql.cc +index aab16daf9..8a2a5092a 100644 +--- a/modules/gmysqlbackend/smysql.cc ++++ b/modules/gmysqlbackend/smysql.cc +@@ -182,7 +182,7 @@ public: + // prepare for result + d_resnum = mysql_stmt_num_rows(d_stmt); + +- if (d_resnum>0 && d_res_bind == NULL) { ++ if (d_resnum > 0 && d_res_bind == nullptr) { + MYSQL_RES* meta = mysql_stmt_result_metadata(d_stmt); + d_fnum = static_cast<int>(mysql_num_fields(meta)); // ensure correct number of fields + d_res_bind = new MYSQL_BIND[d_fnum]; +@@ -201,12 +201,17 @@ public: + } + + mysql_free_result(meta); +- +- if ((err = mysql_stmt_bind_result(d_stmt, d_res_bind))) { +- string error(mysql_stmt_error(d_stmt)); +- releaseStatement(); +- throw SSqlException("Could not bind parameters to mysql statement: " + d_query + string(": ") + error); +- } ++ } ++ ++ /* we need to bind the results array again because a call to mysql_stmt_next_result() followed ++ by a call to mysql_stmt_store_result() might have invalidated it (the first one sets ++ stmt->bind_result_done to false, causing the second to reset the existing binding), ++ and we can't bind it right after the call to mysql_stmt_store_result() if it returned ++ no rows, because then the statement 'contains no metadata' */ ++ if (d_res_bind != nullptr && (err = mysql_stmt_bind_result(d_stmt, d_res_bind))) { ++ string error(mysql_stmt_error(d_stmt)); ++ releaseStatement(); ++ throw SSqlException("Could not bind parameters to mysql statement: " + d_query + string(": ") + error); + } + } + +@@ -252,13 +259,13 @@ public: + if ((err = mysql_stmt_store_result(d_stmt))) { + string error(mysql_stmt_error(d_stmt)); + releaseStatement(); +- throw SSqlException("Could not store mysql statement: " + d_query + string(": ") + error); ++ throw SSqlException("Could not store mysql statement while processing additional sets: " + d_query + string(": ") + error); + } + d_resnum = mysql_stmt_num_rows(d_stmt); + // XXX: For some reason mysql_stmt_result_metadata returns NULL here, so we cannot + // ensure row field count matches first result set. +- if (d_resnum>0) { // ignore empty result set +- if ((err = mysql_stmt_bind_result(d_stmt, d_res_bind))) { ++ if (d_resnum > 0) { // ignore empty result set ++ if (d_res_bind != nullptr && (err = mysql_stmt_bind_result(d_stmt, d_res_bind))) { + string error(mysql_stmt_error(d_stmt)); + releaseStatement(); + throw SSqlException("Could not bind parameters to mysql statement: " + d_query + string(": ") + error); +-- +2.19.1 + diff -Nru pdns-4.0.3/debian/patches/911659-auth-reanimate-backends.patch pdns-4.0.3/debian/patches/911659-auth-reanimate-backends.patch --- pdns-4.0.3/debian/patches/911659-auth-reanimate-backends.patch 1970-01-01 00:00:00.000000000 +0000 +++ pdns-4.0.3/debian/patches/911659-auth-reanimate-backends.patch 2018-11-10 13:36:22.000000000 +0000 @@ -0,0 +1,228 @@ +From 8e4c354790ff43ca750a58c504ee31e570462ff8 Mon Sep 17 00:00:00 2001 +From: Chris Hofstaedtler <chris.hofstaedt...@deduktiva.com> +Date: Sat, 10 Nov 2018 15:26:01 +0100 +Subject: [PATCH] auth: reanimate opendbx, lua, ldapbackend + +Minimal version of cf8c91f3d30bdab55725c4b74f7753b7bd1f3c82, +originally by Kees Monshouwer <min...@monshouwer.org> +--- + modules/ldapbackend/ldapbackend.cc | 4 ++-- + modules/ldapbackend/ldapbackend.hh | 2 +- + modules/luabackend/luabackend.hh | 2 +- + modules/luabackend/minimal.cc | 4 ++-- + modules/opendbxbackend/odbxbackend.cc | 26 +++++++++++--------------- + modules/opendbxbackend/odbxbackend.hh | 12 ++++++------ + 6 files changed, 23 insertions(+), 27 deletions(-) + +diff --git a/modules/ldapbackend/ldapbackend.cc b/modules/ldapbackend/ldapbackend.cc +index 3ed7574f0..f315a7aff 100644 +--- a/modules/ldapbackend/ldapbackend.cc ++++ b/modules/ldapbackend/ldapbackend.cc +@@ -481,7 +481,7 @@ bool LdapBackend::get( DNSResourceRecord &rr ) + + + +- bool LdapBackend::getDomainInfo( const string& domain, DomainInfo& di ) ++ bool LdapBackend::getDomainInfo( const DNSName& domain, DomainInfo& di ) + { + string filter; + SOAData sd; +@@ -489,7 +489,7 @@ bool LdapBackend::get( DNSResourceRecord &rr ) + + + // search for SOARecord of domain +- filter = "(&(associatedDomain=" + toLower( m_pldap->escape( domain ) ) + ")(SOARecord=*))"; ++ filter = "(&(associatedDomain=" + toLower( m_pldap->escape( domain.toStringRootDot() ) ) + ")(SOARecord=*))"; + m_msgid = m_pldap->search( getArg( "basedn" ), LDAP_SCOPE_SUBTREE, filter, attronly ); + m_pldap->getSearchEntry( m_msgid, m_result ); + +diff --git a/modules/ldapbackend/ldapbackend.hh b/modules/ldapbackend/ldapbackend.hh +index d2fb3bb4c..4f2656bf4 100644 +--- a/modules/ldapbackend/ldapbackend.hh ++++ b/modules/ldapbackend/ldapbackend.hh +@@ -129,7 +129,7 @@ class LdapBackend : public DNSBackend + bool prepare_simple(); + bool prepare_strict(); + +- bool getDomainInfo( const string& domain, DomainInfo& di ); ++ bool getDomainInfo( const DNSName& domain, DomainInfo& di ) override; + + public: + +diff --git a/modules/luabackend/luabackend.hh b/modules/luabackend/luabackend.hh +index b658af576..0e95e6c84 100644 +--- a/modules/luabackend/luabackend.hh ++++ b/modules/luabackend/luabackend.hh +@@ -58,7 +58,7 @@ public: + void lookup(const QType &qtype, const DNSName &qname, DNSPacket *p, int domain_id); + bool get(DNSResourceRecord &rr); + //! fills the soadata struct with the SOA details. Returns false if there is no SOA. +- bool getSOA(const string &name, SOAData &soadata, DNSPacket *p=0); ++ bool getSOA(const DNSName &name, SOAData &soadata, DNSPacket *p=0) override; + + + // MASTER BACKEND +diff --git a/modules/luabackend/minimal.cc b/modules/luabackend/minimal.cc +index 0f8e3df48..816943b4f 100644 +--- a/modules/luabackend/minimal.cc ++++ b/modules/luabackend/minimal.cc +@@ -172,7 +172,7 @@ bool LUABackend::get(DNSResourceRecord &rr) { + return !rr.content.empty(); + } + +-bool LUABackend::getSOA(const string &name, SOAData &soadata, DNSPacket *p) { ++bool LUABackend::getSOA(const DNSName &name, SOAData &soadata, DNSPacket *p) { + if (logging) + L << Logger::Info << backend_name << "(getsoa) BEGIN" << endl; + +@@ -180,7 +180,7 @@ bool LUABackend::getSOA(const string &name, SOAData &soadata, DNSPacket *p) { + + lua_rawgeti(lua, LUA_REGISTRYINDEX, f_lua_getsoa); + +- lua_pushstring(lua, name.c_str()); ++ lua_pushstring(lua, name.toString().c_str()); + + if(lua_pcall(lua, 1, 1, f_lua_exec_error) != 0) { + string e = backend_name + lua_tostring(lua, -1); +diff --git a/modules/opendbxbackend/odbxbackend.cc b/modules/opendbxbackend/odbxbackend.cc +index c868a8010..0bd001540 100644 +--- a/modules/opendbxbackend/odbxbackend.cc ++++ b/modules/opendbxbackend/odbxbackend.cc +@@ -105,7 +105,7 @@ OdbxBackend::~OdbxBackend() + + + +-bool OdbxBackend::getDomainInfo( const string& domain, DomainInfo& di ) ++bool OdbxBackend::getDomainInfo( const DNSName& domain, DomainInfo& di ) + { + const char* tmp; + +@@ -115,7 +115,7 @@ bool OdbxBackend::getDomainInfo( const string& domain, DomainInfo& di ) + DLOG( L.log( m_myname + " getDomainInfo()", Logger::Debug ) ); + + string stmt = getArg( "sql-zoneinfo" ); +- string& stmtref = strbind( ":name", escape( toLower( domain ), READ ), stmt ); ++ string& stmtref = strbind( ":name", escape( domain.makeLowerCase().toStringRootDot(), READ ), stmt ); + + if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; } + if( !getRecord( READ ) ) { return false; } +@@ -201,7 +201,7 @@ bool OdbxBackend::getSOA( const DNSName& domain, SOAData& sd, DNSPacket* p ) + DLOG( L.log( m_myname + " getSOA()", Logger::Debug ) ); + + string stmt = getArg( "sql-lookupsoa" ); +- string& stmtref = strbind( ":name", escape( domain.toStringNoDot(), READ ), stmt ); ++ string& stmtref = strbind( ":name", escape( domain.makeLowerCase().toStringNoDot(), READ ), stmt ); + + if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; } + if( !getRecord( READ ) ) { return false; } +@@ -345,8 +345,7 @@ void OdbxBackend::lookup( const QType& qtype, const DNSName& qname, DNSPacket* d + stmtref = strbind( ":id", string( m_buffer, len ), stmtref ); + } + +- string tmp = qname.toStringNoDot(); +- stmtref = strbind( ":name", escape( toLowerByRef( tmp ), READ ), stmtref ); ++ stmtref = strbind( ":name", escape( qname.makeLowerCase().toStringRootDot(), READ ), stmtref ); + + if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) + { +@@ -509,14 +508,14 @@ void OdbxBackend::setNotified( uint32_t domain_id, uint32_t serial ) + + + +-bool OdbxBackend::isMaster( const string& domain, const string& ip ) ++bool OdbxBackend::isMaster( const DNSName& domain, const string& ip ) + { + try + { + DLOG( L.log( m_myname + " isMaster()", Logger::Debug ) ); + + string stmt = getArg( "sql-master" ); +- string& stmtref = strbind( ":name", escape( toLower( domain ), READ ), stmt ); ++ string& stmtref = strbind( ":name", escape( domain.makeLowerCase().toStringRootDot(), READ ), stmt ); + + if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; } + if( !getRecord( READ ) ) { return false; } +@@ -589,7 +588,7 @@ void OdbxBackend::getUpdatedMasters( vector<DomainInfo>* updated ) + + + +-bool OdbxBackend::superMasterBackend( const string& ip, const string& domain, const vector<DNSResourceRecord>& set, string *nameserver, string* account, DNSBackend** ddb ) ++bool OdbxBackend::superMasterBackend( const string& ip, const DNSName& domain, const vector<DNSResourceRecord>& set, string *nameserver, string* account, DNSBackend** ddb ) + { + try + { +@@ -633,7 +632,7 @@ bool OdbxBackend::superMasterBackend( const string& ip, const string& domain, co + + + +-bool OdbxBackend::createSlaveDomain( const string& ip, const string& domain, const string &nameserver, const string& account ) ++bool OdbxBackend::createSlaveDomain( const string& ip, const DNSName& domain, const string &nameserver, const string& account ) + { + try + { +@@ -645,8 +644,7 @@ bool OdbxBackend::createSlaveDomain( const string& ip, const string& domain, con + return false; + } + +- string tmp = domain; +- int len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-slave" ).c_str(), escape( toLowerByRef( tmp ), WRITE ).c_str(), ++ int len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-slave" ).c_str(), escape( domain.makeLowerCase().toStringRootDot(), WRITE ).c_str(), + escape( ip, WRITE ).c_str(), escape( account, WRITE ).c_str() ); + + if( len < 0 ) +@@ -686,8 +684,6 @@ bool OdbxBackend::feedRecord( const DNSResourceRecord& rr, string *ordername ) + return false; + } + +- string tmp = rr.qname.toStringNoDot(); +- + unsigned int priority=0; + string content(rr.content); + +@@ -700,7 +696,7 @@ bool OdbxBackend::feedRecord( const DNSResourceRecord& rr, string *ordername ) + } + + int len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-record" ).c_str(), rr.domain_id, +- escape( toLowerByRef( tmp ), WRITE ).c_str(), rr.qtype.getName().c_str(), rr.ttl, priority, ++ escape( rr.qname.makeLowerCase().toStringRootDot(), WRITE ).c_str(), rr.qtype.getName().c_str(), rr.ttl, priority, + escape( content, WRITE ).c_str() ); + + if( len < 0 ) +@@ -728,7 +724,7 @@ bool OdbxBackend::feedRecord( const DNSResourceRecord& rr, string *ordername ) + + + +-bool OdbxBackend::startTransaction( const string& domain, int zoneid ) ++bool OdbxBackend::startTransaction( const DNSName& domain, int zoneid ) + { + try + { +diff --git a/modules/opendbxbackend/odbxbackend.hh b/modules/opendbxbackend/odbxbackend.hh +index 81e270348..8f9e27041 100644 +--- a/modules/opendbxbackend/odbxbackend.hh ++++ b/modules/opendbxbackend/odbxbackend.hh +@@ -82,15 +82,15 @@ public: + bool list( const DNSName& target, int domain_id, bool include_disabled=false ); + bool get( DNSResourceRecord& rr ); + +- bool startTransaction( const string& domain, int domain_id ); ++ bool startTransaction( const DNSName& domain, int domain_id ) override; + bool commitTransaction(); + bool abortTransaction(); + +- bool isMaster( const string& domain, const string& ip ); +- bool getDomainInfo( const string& domain, DomainInfo& di ); +- bool feedRecord( const DNSResourceRecord& rr, string *ordername=0 ); +- bool createSlaveDomain( const string& ip, const string& domain, const string &nameserver, const string& account ); +- bool superMasterBackend( const string& ip, const string& domain, const vector<DNSResourceRecord>& nsset, string *nameserver, string* account, DNSBackend** ddb ); ++ bool isMaster( const DNSName& domain, const string& ip ) override; ++ bool getDomainInfo( const DNSName& domain, DomainInfo& di ) override; ++ bool feedRecord( const DNSResourceRecord& rr, string *ordername=0 ) override; ++ bool createSlaveDomain( const string& ip, const DNSName& domain, const string &nameserver, const string& account ) override; ++ bool superMasterBackend( const string& ip, const DNSName& domain, const vector<DNSResourceRecord>& nsset, string *nameserver, string* account, DNSBackend** ddb ) override; + + void getUpdatedMasters( vector<DomainInfo>* updated ); + void getUnfreshSlaveInfos( vector<DomainInfo>* unfresh ); +-- +2.19.1 + diff -Nru pdns-4.0.3/debian/patches/CVE-2018-1046.patch pdns-4.0.3/debian/patches/CVE-2018-1046.patch --- pdns-4.0.3/debian/patches/CVE-2018-1046.patch 1970-01-01 00:00:00.000000000 +0000 +++ pdns-4.0.3/debian/patches/CVE-2018-1046.patch 2018-11-10 13:36:22.000000000 +0000 @@ -0,0 +1,22 @@ +From f9c57c98da1b1007a51680629b667d57d9b702b8 Mon Sep 17 00:00:00 2001 +From: Remi Gacogne <remi.gaco...@powerdns.com> +Date: Tue, 5 Dec 2017 17:07:19 +0100 +Subject: [PATCH] dnsreplay: Bail out on a too small outgoing buffer + +--- + pdns/dnsreplay.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/pdns/dnsreplay.cc b/pdns/dnsreplay.cc +index 4c5f218c99..a671472f6f 100644 +--- a/pdns/dnsreplay.cc ++++ b/pdns/dnsreplay.cc +@@ -595,7 +595,7 @@ static void addECSOption(char* packet, const size_t& packetSize, uint16_t* len, + + uint16_t arcount = ntohs(dh->arcount); + /* does it fit in the existing buffer? */ +- if (packetSize - *len > EDNSRR.size()) { ++ if (packetSize > *len && packetSize - *len > EDNSRR.size()) { + arcount++; + dh->arcount = htons(arcount); + memcpy(packet + *len, EDNSRR.c_str(), EDNSRR.size()); diff -Nru pdns-4.0.3/debian/patches/CVE-2018-10851.patch pdns-4.0.3/debian/patches/CVE-2018-10851.patch --- pdns-4.0.3/debian/patches/CVE-2018-10851.patch 1970-01-01 00:00:00.000000000 +0000 +++ pdns-4.0.3/debian/patches/CVE-2018-10851.patch 2018-11-10 13:36:22.000000000 +0000 @@ -0,0 +1,541 @@ +diff -ru pdns-4.0.5.orig/modules/bindbackend/binddnssec.cc pdns-4.0.5/modules/bindbackend/binddnssec.cc +--- pdns-4.0.5.orig/modules/bindbackend/binddnssec.cc 2017-11-27 12:38:48.000000000 +0100 ++++ pdns-4.0.5/modules/bindbackend/binddnssec.cc 2018-10-10 11:30:03.159903279 +0200 +@@ -164,9 +164,8 @@ + + static int maxNSEC3Iterations=::arg().asNum("max-nsec3-iterations"); + if(ns3p) { +- NSEC3PARAMRecordContent* tmp=dynamic_cast<NSEC3PARAMRecordContent*>(DNSRecordContent::mastermake(QType::NSEC3PARAM, 1, value)); ++ auto tmp=std::dynamic_pointer_cast<NSEC3PARAMRecordContent>(DNSRecordContent::mastermake(QType::NSEC3PARAM, 1, value)); + *ns3p = *tmp; +- delete tmp; + + if (ns3p->d_iterations > maxNSEC3Iterations) { + ns3p->d_iterations = maxNSEC3Iterations; +diff -ru pdns-4.0.5.orig/modules/tinydnsbackend/tinydnsbackend.cc pdns-4.0.5/modules/tinydnsbackend/tinydnsbackend.cc +--- pdns-4.0.5.orig/modules/tinydnsbackend/tinydnsbackend.cc 2017-11-27 12:38:48.000000000 +0100 ++++ pdns-4.0.5/modules/tinydnsbackend/tinydnsbackend.cc 2018-10-10 11:30:03.159903279 +0200 +@@ -300,10 +300,9 @@ + dr.d_type = rr.qtype.getCode(); + dr.d_clen = val.size()-pr.d_pos; + +- DNSRecordContent *drc = DNSRecordContent::mastermake(dr, pr); ++ auto drc = DNSRecordContent::mastermake(dr, pr); + rr.content = drc->getZoneRepresentation(); + DLOG(cerr<<"CONTENT: "<<rr.content<<endl); +- delete drc; + } + catch (...) { + if (d_ignorebogus) { +diff -ru pdns-4.0.5.orig/pdns/dnsparser.cc pdns-4.0.5/pdns/dnsparser.cc +--- pdns-4.0.5.orig/pdns/dnsparser.cc 2017-11-27 12:38:48.000000000 +0100 ++++ pdns-4.0.5/pdns/dnsparser.cc 2018-10-10 11:30:03.159903279 +0200 +@@ -121,54 +121,42 @@ + return ret; + } + +-DNSRecordContent* DNSRecordContent::mastermake(const DNSRecord &dr, +- PacketReader& pr) ++std::shared_ptr<DNSRecordContent> DNSRecordContent::mastermake(const DNSRecord &dr, ++ PacketReader& pr) + { + uint16_t searchclass = (dr.d_type == QType::OPT) ? 1 : dr.d_class; // class is invalid for OPT + + typemap_t::const_iterator i=getTypemap().find(make_pair(searchclass, dr.d_type)); + if(i==getTypemap().end() || !i->second) { +- return new UnknownRecordContent(dr, pr); ++ return std::make_shared<UnknownRecordContent>(dr, pr); + } + + return i->second(dr, pr); + } + +-DNSRecordContent* DNSRecordContent::mastermake(uint16_t qtype, uint16_t qclass, +- const string& content) ++std::shared_ptr<DNSRecordContent> DNSRecordContent::mastermake(uint16_t qtype, uint16_t qclass, ++ const string& content) + { + zmakermap_t::const_iterator i=getZmakermap().find(make_pair(qclass, qtype)); + if(i==getZmakermap().end()) { +- return new UnknownRecordContent(content); ++ return std::make_shared<UnknownRecordContent>(content); + } + + return i->second(content); + } + +-std::unique_ptr<DNSRecordContent> DNSRecordContent::makeunique(uint16_t qtype, uint16_t qclass, +- const string& content) +-{ +- zmakermap_t::const_iterator i=getZmakermap().find(make_pair(qclass, qtype)); +- if(i==getZmakermap().end()) { +- return std::unique_ptr<DNSRecordContent>(new UnknownRecordContent(content)); +- } +- +- return std::unique_ptr<DNSRecordContent>(i->second(content)); +-} +- +- +-DNSRecordContent* DNSRecordContent::mastermake(const DNSRecord &dr, PacketReader& pr, uint16_t oc) { ++std::shared_ptr<DNSRecordContent> DNSRecordContent::mastermake(const DNSRecord &dr, PacketReader& pr, uint16_t oc) { + // For opcode UPDATE and where the DNSRecord is an answer record, we don't care about content, because this is + // not used within the prerequisite section of RFC2136, so - we can simply use unknownrecordcontent. + // For section 3.2.3, we do need content so we need to get it properly. But only for the correct Qclasses. + if (oc == Opcode::Update && dr.d_place == DNSResourceRecord::ANSWER && dr.d_class != 1) +- return new UnknownRecordContent(dr, pr); ++ return std::make_shared<UnknownRecordContent>(dr, pr); + + uint16_t searchclass = (dr.d_type == QType::OPT) ? 1 : dr.d_class; // class is invalid for OPT + + typemap_t::const_iterator i=getTypemap().find(make_pair(searchclass, dr.d_type)); + if(i==getTypemap().end() || !i->second) { +- return new UnknownRecordContent(dr, pr); ++ return std::make_shared<UnknownRecordContent>(dr, pr); + } + + return i->second(dr, pr); +diff -ru pdns-4.0.5.orig/pdns/dnsparser.hh pdns-4.0.5/pdns/dnsparser.hh +--- pdns-4.0.5.orig/pdns/dnsparser.hh 2017-11-27 12:38:48.000000000 +0100 ++++ pdns-4.0.5/pdns/dnsparser.hh 2018-10-10 11:30:03.159903279 +0200 +@@ -166,10 +166,9 @@ + class DNSRecordContent + { + public: +- static DNSRecordContent* mastermake(const DNSRecord &dr, PacketReader& pr); +- static DNSRecordContent* mastermake(const DNSRecord &dr, PacketReader& pr, uint16_t opcode); +- static DNSRecordContent* mastermake(uint16_t qtype, uint16_t qclass, const string& zone); +- static std::unique_ptr<DNSRecordContent> makeunique(uint16_t qtype, uint16_t qclass, const string& content); ++ static std::shared_ptr<DNSRecordContent> mastermake(const DNSRecord &dr, PacketReader& pr); ++ static std::shared_ptr<DNSRecordContent> mastermake(const DNSRecord &dr, PacketReader& pr, uint16_t opcode); ++ static std::shared_ptr<DNSRecordContent> mastermake(uint16_t qtype, uint16_t qclass, const string& zone); + + virtual std::string getZoneRepresentation(bool noDot=false) const = 0; + virtual ~DNSRecordContent() {} +@@ -198,8 +197,8 @@ + + void doRecordCheck(const struct DNSRecord&){} + +- typedef DNSRecordContent* makerfunc_t(const struct DNSRecord& dr, PacketReader& pr); +- typedef DNSRecordContent* zmakerfunc_t(const string& str); ++ typedef std::shared_ptr<DNSRecordContent> makerfunc_t(const struct DNSRecord& dr, PacketReader& pr); ++ typedef std::shared_ptr<DNSRecordContent> zmakerfunc_t(const string& str); + + static void regist(uint16_t cl, uint16_t ty, makerfunc_t* f, zmakerfunc_t* z, const char* name) + { +diff -ru pdns-4.0.5.orig/pdns/dnsrecords.cc pdns-4.0.5/pdns/dnsrecords.cc +--- pdns-4.0.5.orig/pdns/dnsrecords.cc 2017-11-27 12:38:48.000000000 +0100 ++++ pdns-4.0.5/pdns/dnsrecords.cc 2018-10-10 11:30:03.159903279 +0200 +@@ -386,19 +386,19 @@ + { + regist(1, QType::EUI48, &make, &make, "EUI48"); + } +-DNSRecordContent* EUI48RecordContent::make(const DNSRecord &dr, PacketReader& pr) ++std::shared_ptr<DNSRecordContent> EUI48RecordContent::make(const DNSRecord &dr, PacketReader& pr) + { + if(dr.d_clen!=6) + throw MOADNSException("Wrong size for EUI48 record"); + +- EUI48RecordContent* ret=new EUI48RecordContent(); ++ auto ret=std::make_shared<EUI48RecordContent>(); + pr.copyRecord((uint8_t*) &ret->d_eui48, 6); + return ret; + } +-DNSRecordContent* EUI48RecordContent::make(const string& zone) ++std::shared_ptr<DNSRecordContent> EUI48RecordContent::make(const string& zone) + { + // try to parse +- EUI48RecordContent *ret=new EUI48RecordContent(); ++ auto ret=std::make_shared<EUI48RecordContent>(); + // format is 6 hex bytes and dashes + if (sscanf(zone.c_str(), "%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx", + ret->d_eui48, ret->d_eui48+1, ret->d_eui48+2, +@@ -429,19 +429,19 @@ + { + regist(1, QType::EUI64, &make, &make, "EUI64"); + } +-DNSRecordContent* EUI64RecordContent::make(const DNSRecord &dr, PacketReader& pr) ++std::shared_ptr<DNSRecordContent> EUI64RecordContent::make(const DNSRecord &dr, PacketReader& pr) + { + if(dr.d_clen!=8) + throw MOADNSException("Wrong size for EUI64 record"); + +- EUI64RecordContent* ret=new EUI64RecordContent(); ++ auto ret=std::make_shared<EUI64RecordContent>(); + pr.copyRecord((uint8_t*) &ret->d_eui64, 8); + return ret; + } +-DNSRecordContent* EUI64RecordContent::make(const string& zone) ++std::shared_ptr<DNSRecordContent> EUI64RecordContent::make(const string& zone) + { + // try to parse +- EUI64RecordContent *ret=new EUI64RecordContent(); ++ auto ret=std::make_shared<EUI64RecordContent>(); + // format is 8 hex bytes and dashes + if (sscanf(zone.c_str(), "%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx", + ret->d_eui64, ret->d_eui64+1, ret->d_eui64+2, +diff -ru pdns-4.0.5.orig/pdns/dnsrecords.hh pdns-4.0.5/pdns/dnsrecords.hh +--- pdns-4.0.5.orig/pdns/dnsrecords.hh 2017-11-27 12:38:48.000000000 +0100 ++++ pdns-4.0.5/pdns/dnsrecords.hh 2018-10-10 11:30:03.159903279 +0200 +@@ -33,8 +33,8 @@ + RNAME##RecordContent(const string& zoneData); \ + static void report(void); \ + static void unreport(void); \ +- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr); \ +- static DNSRecordContent* make(const string& zonedata); \ ++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); \ ++ static std::shared_ptr<DNSRecordContent> make(const string& zonedata); \ + string getZoneRepresentation(bool noDot=false) const override; \ + void toPacket(DNSPacketWriter& pw) override; \ + uint16_t getType() const override { return QType::RNAME; } \ +@@ -466,8 +466,8 @@ + {} + NSECRecordContent(const string& content, const string& zone=""); //FIXME400: DNSName& zone? + +- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr); +- static DNSRecordContent* make(const string& content); ++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); ++ static std::shared_ptr<DNSRecordContent> make(const string& content); + string getZoneRepresentation(bool noDot=false) const override; + void toPacket(DNSPacketWriter& pw) override; + uint16_t getType() const override +@@ -487,8 +487,8 @@ + {} + NSEC3RecordContent(const string& content, const string& zone=""); //FIXME400: DNSName& zone? + +- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr); +- static DNSRecordContent* make(const string& content); ++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); ++ static std::shared_ptr<DNSRecordContent> make(const string& content); + string getZoneRepresentation(bool noDot=false) const override; + void toPacket(DNSPacketWriter& pw) override; + +@@ -516,8 +516,8 @@ + {} + NSEC3PARAMRecordContent(const string& content, const string& zone=""); // FIXME400: DNSName& zone? + +- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr); +- static DNSRecordContent* make(const string& content); ++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); ++ static std::shared_ptr<DNSRecordContent> make(const string& content); + string getZoneRepresentation(bool noDot=false) const override; + void toPacket(DNSPacketWriter& pw) override; + +@@ -541,8 +541,8 @@ + {} + LOCRecordContent(const string& content, const string& zone=""); + +- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr); +- static DNSRecordContent* make(const string& content); ++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); ++ static std::shared_ptr<DNSRecordContent> make(const string& content); + string getZoneRepresentation(bool noDot=false) const override; + void toPacket(DNSPacketWriter& pw) override; + +@@ -565,8 +565,8 @@ + {} + WKSRecordContent(const string& content, const string& zone=""); // FIXME400: DNSName& zone? + +- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr); +- static DNSRecordContent* make(const string& content); ++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); ++ static std::shared_ptr<DNSRecordContent> make(const string& content); + string getZoneRepresentation(bool noDot=false) const override; + void toPacket(DNSPacketWriter& pw) override; + +@@ -580,8 +580,8 @@ + public: + EUI48RecordContent() {}; + static void report(void); +- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr); +- static DNSRecordContent* make(const string& zone); // FIXME400: DNSName& zone? ++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); ++ static std::shared_ptr<DNSRecordContent> make(const string& zone); // FIXME400: DNSName& zone? + string getZoneRepresentation(bool noDot=false) const override; + void toPacket(DNSPacketWriter& pw) override; + uint16_t getType() const override { return QType::EUI48; } +@@ -595,8 +595,8 @@ + public: + EUI64RecordContent() {}; + static void report(void); +- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr); +- static DNSRecordContent* make(const string& zone); // FIXME400: DNSName& zone? ++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); ++ static std::shared_ptr<DNSRecordContent> make(const string& zone); // FIXME400: DNSName& zone? + string getZoneRepresentation(bool noDot=false) const override; + void toPacket(DNSPacketWriter& pw) override; + uint16_t getType() const override { return QType::EUI64; } +@@ -643,9 +643,9 @@ + }; + + #define boilerplate(RNAME, RTYPE) \ +-RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const DNSRecord& dr, PacketReader& pr) \ ++std::shared_ptr<RNAME##RecordContent::DNSRecordContent> RNAME##RecordContent::make(const DNSRecord& dr, PacketReader& pr) \ + { \ +- return new RNAME##RecordContent(dr, pr); \ ++ return std::make_shared<RNAME##RecordContent>(dr, pr); \ + } \ + \ + RNAME##RecordContent::RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr) \ +@@ -654,9 +654,9 @@ + xfrPacket(pr); \ + } \ + \ +-RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const string& zonedata) \ ++std::shared_ptr<RNAME##RecordContent::DNSRecordContent> RNAME##RecordContent::make(const string& zonedata) \ + { \ +- return new RNAME##RecordContent(zonedata); \ ++ return std::make_shared<RNAME##RecordContent>(zonedata); \ + } \ + \ + void RNAME##RecordContent::toPacket(DNSPacketWriter& pw) \ +diff -ru pdns-4.0.5.orig/pdns/nsecrecords.cc pdns-4.0.5/pdns/nsecrecords.cc +--- pdns-4.0.5.orig/pdns/nsecrecords.cc 2017-11-27 12:38:48.000000000 +0100 ++++ pdns-4.0.5/pdns/nsecrecords.cc 2018-10-10 11:30:03.159903279 +0200 +@@ -29,9 +29,9 @@ + regist(1, 47, &make, &make, "NSEC"); + } + +-DNSRecordContent* NSECRecordContent::make(const string& content) ++std::shared_ptr<DNSRecordContent> NSECRecordContent::make(const string& content) + { +- return new NSECRecordContent(content); ++ return std::make_shared<NSECRecordContent>(content); + } + + NSECRecordContent::NSECRecordContent(const string& content, const string& zone) +@@ -81,9 +81,9 @@ + pw.xfrBlob(tmp); + } + +-NSECRecordContent::DNSRecordContent* NSECRecordContent::make(const DNSRecord &dr, PacketReader& pr) ++std::shared_ptr<NSECRecordContent::DNSRecordContent> NSECRecordContent::make(const DNSRecord &dr, PacketReader& pr) + { +- NSECRecordContent* ret=new NSECRecordContent(); ++ auto ret=std::make_shared<NSECRecordContent>(); + pr.xfrName(ret->d_next); + string bitmap; + pr.xfrBlob(bitmap); +@@ -136,9 +136,9 @@ + regist(1, 50, &make, &make, "NSEC3"); + } + +-DNSRecordContent* NSEC3RecordContent::make(const string& content) ++std::shared_ptr<DNSRecordContent> NSEC3RecordContent::make(const string& content) + { +- return new NSEC3RecordContent(content); ++ return std::make_shared<NSEC3RecordContent>(content); + } + + NSEC3RecordContent::NSEC3RecordContent(const string& content, const string& zone) +@@ -203,9 +203,9 @@ + } + } + +-NSEC3RecordContent::DNSRecordContent* NSEC3RecordContent::make(const DNSRecord &dr, PacketReader& pr) ++std::shared_ptr<NSEC3RecordContent::DNSRecordContent> NSEC3RecordContent::make(const DNSRecord &dr, PacketReader& pr) + { +- NSEC3RecordContent* ret=new NSEC3RecordContent(); ++ auto ret=std::make_shared<NSEC3RecordContent>(); + pr.xfr8BitInt(ret->d_algorithm); + pr.xfr8BitInt(ret->d_flags); + pr.xfr16BitInt(ret->d_iterations); +@@ -273,9 +273,9 @@ + regist(254, 51, &make, &make, "NSEC3PARAM"); + } + +-DNSRecordContent* NSEC3PARAMRecordContent::make(const string& content) ++std::shared_ptr<DNSRecordContent> NSEC3PARAMRecordContent::make(const string& content) + { +- return new NSEC3PARAMRecordContent(content); ++ return std::make_shared<NSEC3PARAMRecordContent>(content); + } + + NSEC3PARAMRecordContent::NSEC3PARAMRecordContent(const string& content, const string& zone) +@@ -297,9 +297,9 @@ + pw.xfrBlob(d_salt); + } + +-NSEC3PARAMRecordContent::DNSRecordContent* NSEC3PARAMRecordContent::make(const DNSRecord &dr, PacketReader& pr) ++std::shared_ptr<NSEC3PARAMRecordContent::DNSRecordContent> NSEC3PARAMRecordContent::make(const DNSRecord &dr, PacketReader& pr) + { +- NSEC3PARAMRecordContent* ret=new NSEC3PARAMRecordContent(); ++ auto ret=std::make_shared<NSEC3PARAMRecordContent>(); + pr.xfr8BitInt(ret->d_algorithm); + pr.xfr8BitInt(ret->d_flags); + pr.xfr16BitInt(ret->d_iterations); +diff -ru pdns-4.0.5.orig/pdns/pdnsutil.cc pdns-4.0.5/pdns/pdnsutil.cc +--- pdns-4.0.5.orig/pdns/pdnsutil.cc 2017-11-27 12:38:48.000000000 +0100 ++++ pdns-4.0.5/pdns/pdnsutil.cc 2018-10-10 11:30:03.159903279 +0200 +@@ -1414,15 +1414,15 @@ + if(rr.qtype.getCode() == QType::DNSKEY) { + cerr<<"got DNSKEY!"<<endl; + apex=rr.qname; +- drc = *dynamic_cast<DNSKEYRecordContent*>(DNSRecordContent::mastermake(QType::DNSKEY, 1, rr.content)); ++ drc = *std::dynamic_pointer_cast<DNSKEYRecordContent>(DNSRecordContent::mastermake(QType::DNSKEY, 1, rr.content)); + } + else if(rr.qtype.getCode() == QType::RRSIG) { + cerr<<"got RRSIG"<<endl; +- rrc = *dynamic_cast<RRSIGRecordContent*>(DNSRecordContent::mastermake(QType::RRSIG, 1, rr.content)); ++ rrc = *std::dynamic_pointer_cast<RRSIGRecordContent>(DNSRecordContent::mastermake(QType::RRSIG, 1, rr.content)); + } + else if(rr.qtype.getCode() == QType::DS) { + cerr<<"got DS"<<endl; +- dsrc = *dynamic_cast<DSRecordContent*>(DNSRecordContent::mastermake(QType::DS, 1, rr.content)); ++ dsrc = *std::dynamic_pointer_cast<DSRecordContent>(DNSRecordContent::mastermake(QType::DS, 1, rr.content)); + } + else { + qname = rr.qname; +@@ -1581,7 +1581,7 @@ bool showZone(DNSSECKeeper& dk, const DNSName& zone) + B.lookup(QType(QType::DNSKEY), zone); + while(B.get(rr)) { + if (rr.qtype != QType::DNSKEY) continue; +- keys.push_back(*dynamic_cast<DNSKEYRecordContent*>(DNSKEYRecordContent::make(rr.getZoneRepresentation()))); ++ keys.push_back(DNSKEYRecordContent(rr.getZoneRepresentation())); + } + + if(keys.empty()) { +diff -ru pdns-4.0.5.orig/pdns/sillyrecords.cc pdns-4.0.5/pdns/sillyrecords.cc +--- pdns-4.0.5.orig/pdns/sillyrecords.cc 2017-11-27 12:38:48.000000000 +0100 ++++ pdns-4.0.5/pdns/sillyrecords.cc 2018-10-10 11:30:08.046519093 +0200 +@@ -159,9 +159,9 @@ + regist(254, QType::LOC, &make, &make, "LOC"); + } + +-DNSRecordContent* LOCRecordContent::make(const string& content) ++std::shared_ptr<DNSRecordContent> LOCRecordContent::make(const string& content) + { +- return new LOCRecordContent(content); ++ return std::make_shared<LOCRecordContent>(content); + } + + +@@ -177,9 +177,9 @@ + pw.xfr32BitInt(d_altitude); + } + +-LOCRecordContent::DNSRecordContent* LOCRecordContent::make(const DNSRecord &dr, PacketReader& pr) ++std::shared_ptr<LOCRecordContent::DNSRecordContent> LOCRecordContent::make(const DNSRecord &dr, PacketReader& pr) + { +- LOCRecordContent* ret=new LOCRecordContent(); ++ auto ret=std::make_shared<LOCRecordContent>(); + pr.xfr8BitInt(ret->d_version); + pr.xfr8BitInt(ret->d_size); + pr.xfr8BitInt(ret->d_horizpre); +diff -ru pdns-4.0.5.orig/pdns/speedtest.cc pdns-4.0.5/pdns/speedtest.cc +--- pdns-4.0.5.orig/pdns/speedtest.cc 2017-11-27 12:38:48.000000000 +0100 ++++ pdns-4.0.5/pdns/speedtest.cc 2018-10-10 11:30:08.046519093 +0200 +@@ -207,9 +207,8 @@ + + void operator()() const + { +- DNSRecordContent*drc = DNSRecordContent::mastermake(QType::A, 1, +- "1.2.3.4"); +- delete drc; ++ auto drc = DNSRecordContent::mastermake(QType::A, 1, ++ "1.2.3.4"); + } + }; + +@@ -281,8 +280,8 @@ + DNSPacketWriter pw(packet, DNSName("outpost.ds9a.nl"), d_type); + for(int records = 0; records < d_records; records++) { + pw.startRecord(DNSName("outpost.ds9a.nl"), d_type); +- DNSRecordContent*drc = DNSRecordContent::mastermake(d_type, 1, +- d_content); ++ auto drc = DNSRecordContent::mastermake(d_type, 1, ++ d_content); + drc->toPacket(pw); + delete drc; + } +@@ -309,7 +308,7 @@ + DNSPacketWriter pw(packet, DNSName("outpost.ds9a.nl"), QType::AAAA); + for(int records = 0; records < d_records; records++) { + pw.startRecord(DNSName("outpost.ds9a.nl"), QType::AAAA); +- DNSRecordContent*drc = DNSRecordContent::mastermake(QType::AAAA, 1, "fe80::21d:92ff:fe6d:8441"); ++ auto drc = DNSRecordContent::mastermake(QType::AAAA, 1, "fe80::21d:92ff:fe6d:8441"); + drc->toPacket(pw); + delete drc; + } +@@ -334,7 +333,7 @@ + + for(int records = 0; records < d_records; records++) { + pw.startRecord(DNSName("outpost.ds9a.nl"), QType::SOA); +- DNSRecordContent*drc = DNSRecordContent::mastermake(QType::SOA, 1, "a0.org.afilias-nst.info. noc.afilias-nst.info. 2008758137 1800 900 604800 86400"); ++ auto drc = DNSRecordContent::mastermake(QType::SOA, 1, "a0.org.afilias-nst.info. noc.afilias-nst.info. 2008758137 1800 900 604800 86400"); + drc->toPacket(pw); + delete drc; + } +@@ -356,7 +355,7 @@ + DNSPacketWriter pw(packet, DNSName("outpost.ds9a.nl"), QType::A); + + pw.startRecord(DNSName("ds9a.nl"), QType::NS, 3600, 1, DNSResourceRecord::AUTHORITY); +- DNSRecordContent* drc = DNSRecordContent::mastermake(QType::NS, 1, "ns1.ds9a.nl"); ++ auto drc = DNSRecordContent::mastermake(QType::NS, 1, "ns1.ds9a.nl"); + drc->toPacket(pw); + delete drc; + +diff -ru pdns-4.0.5.orig/pdns/test-dnsrecords_cc.cc pdns-4.0.5/pdns/test-dnsrecords_cc.cc +--- pdns-4.0.5.orig/pdns/test-dnsrecords_cc.cc 2017-11-27 12:38:48.000000000 +0100 ++++ pdns-4.0.5/pdns/test-dnsrecords_cc.cc 2018-10-10 11:30:08.046519093 +0200 +@@ -183,7 +183,7 @@ + try { + std::string recData; + if (q.getCode() != QType::TSIG) { +- boost::scoped_ptr<DNSRecordContent> rec(DNSRecordContent::mastermake(q.getCode(), 1, val.get<1>())); ++ auto rec = DNSRecordContent::mastermake(q.getCode(), 1, val.get<1>()); + BOOST_CHECK_MESSAGE(rec != NULL, "mastermake( " << q.getCode() << ", 1, " << val.get<1>() << ") returned NULL"); + if (rec == NULL) continue; + // now verify the record (note that this will be same as *zone* value (except for certain QTypes) +@@ -268,10 +268,10 @@ + + if (val.get<2>()) { + bool success=true; +- BOOST_WARN_EXCEPTION( { boost::scoped_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(q.getCode(), 1, val.get<1>())); pw.startRecord(DNSName("unit.test"), q.getCode()); drc->toPacket(pw); success=false; }, std::exception, test_dnsrecords_cc_predicate ); ++ BOOST_WARN_EXCEPTION( { std::shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(q.getCode(), 1, val.get<1>())); pw.startRecord(DNSName("unit.test"), q.getCode()); drc->toPacket(pw); success=false; }, std::exception, test_dnsrecords_cc_predicate ); + if (success==false) REC_FAIL_XSUCCESS2(q.getName() << " test #" << n << " has unexpectedly passed"); // a bad record was detected when it was supposed not to be detected + } else { +- BOOST_CHECK_EXCEPTION( { boost::scoped_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(q.getCode(), 1, val.get<1>())); pw.startRecord(DNSName("unit.test"), q.getCode()); drc->toPacket(pw); }, std::exception, test_dnsrecords_cc_predicate ); ++ BOOST_CHECK_EXCEPTION( { std::shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(q.getCode(), 1, val.get<1>())); pw.startRecord(DNSName("unit.test"), q.getCode()); drc->toPacket(pw); }, std::exception, test_dnsrecords_cc_predicate ); + } + }; + } +diff -ru pdns-4.0.5.orig/pdns/toysdig.cc pdns-4.0.5/pdns/toysdig.cc +--- pdns-4.0.5.orig/pdns/toysdig.cc 2017-11-27 12:38:48.000000000 +0100 ++++ pdns-4.0.5/pdns/toysdig.cc 2018-10-10 11:30:08.046519093 +0200 +@@ -102,7 +102,7 @@ + LuaConfigItems::LuaConfigItems() + { + for (const auto &dsRecord : rootDSs) { +- auto ds=unique_ptr<DSRecordContent>(dynamic_cast<DSRecordContent*>(DSRecordContent::make(dsRecord))); ++ auto ds=std::dynamic_pointer_cast<DSRecordContent>(DSRecordContent::make(dsRecord)); + dsAnchors[DNSName(".")].insert(*ds); + } + } +diff -ru pdns-4.0.5.orig/pdns/ws-auth.cc pdns-4.0.5/pdns/ws-auth.cc +--- pdns-4.0.5.orig/pdns/ws-auth.cc 2017-11-27 12:38:48.000000000 +0100 ++++ pdns-4.0.5/pdns/ws-auth.cc 2018-10-10 11:30:08.049852391 +0200 +@@ -291,7 +291,7 @@ + /** Helper to build a record content as needed. */ + static inline string makeRecordContent(const QType& qtype, const string& content, bool noDot) { + // noDot: for backend storage, pass true. for API users, pass false. +- std::unique_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(qtype.getCode(), 1, content)); ++ auto drc = DNSRecordContent::mastermake(qtype.getCode(), QClass::IN, content); + return drc->getZoneRepresentation(noDot); + } + +diff --git a/pdns/dbdnsseckeeper.cc b/pdns/dbdnsseckeeper.cc +index 14e47373d..f115e018b 100644 +--- a/pdns/dbdnsseckeeper.cc ++++ b/pdns/dbdnsseckeeper.cc +@@ -257,9 +257,7 @@ bool DNSSECKeeper::getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* + + static int maxNSEC3Iterations=::arg().asNum("max-nsec3-iterations"); + if(ns3p) { +- NSEC3PARAMRecordContent* tmp=dynamic_cast<NSEC3PARAMRecordContent*>(DNSRecordContent::mastermake(QType::NSEC3PARAM, 1, value)); +- *ns3p = *tmp; +- delete tmp; ++ *ns3p = NSEC3PARAMRecordContent(value); + if (ns3p->d_iterations > maxNSEC3Iterations) { + ns3p->d_iterations = maxNSEC3Iterations; + L<<Logger::Error<<"Number of NSEC3 iterations for zone '"<<zname<<"' is above 'max-nsec3-iterations'. Value adjusted to: "<<maxNSEC3Iterations<<endl; + diff -Nru pdns-4.0.3/debian/patches/series pdns-4.0.3/debian/patches/series --- pdns-4.0.3/debian/patches/series 2017-11-27 22:02:24.000000000 +0000 +++ pdns-4.0.3/debian/patches/series 2018-11-10 13:36:22.000000000 +0000 @@ -1,2 +1,6 @@ 869222-lowercase-qname-before-NSEC-generation.patch +889798-auth-Always-bind-the-results-array-after-executing-a.patch +911659-auth-reanimate-backends.patch CVE-2017-15091-4.0.4.patch +CVE-2018-1046.patch +CVE-2018-10851.patch