X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=pdns%2Fdnsdist.cc;h=75d7c56ea299d30c8a31bd31fb61128377ee9d9c;hb=0ed8f0fa16cbcbbfce4af8729e91ef418563bb8e;hp=96af451cf7f52905ac9b89ef937312c923e6f37f;hpb=59ff0db95099c6e434c1251348f87b0c4e94df27;p=thirdparty%2Fpdns.git diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 96af451cf7..75d7c56ea2 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -37,6 +37,7 @@ #include #endif +#include "dnsdist-systemd.hh" #ifdef HAVE_SYSTEMD #include #endif @@ -81,7 +82,6 @@ using std::thread; bool g_verbose; struct DNSDistStats g_stats; -MetricDefinitionStorage g_metricDefinitions; uint16_t g_maxOutstanding{std::numeric_limits::max()}; uint32_t g_staleCacheEntriesTTL{0}; @@ -193,6 +193,30 @@ struct DelayedPacket DelayPipe* g_delay = nullptr; +std::string DNSQuestion::getTrailingData() const +{ + const char* message = reinterpret_cast(this->dh); + const uint16_t messageLen = getDNSPacketLength(message, this->len); + return std::string(message + messageLen, this->len - messageLen); +} + +bool DNSQuestion::setTrailingData(const std::string& tail) +{ + char* message = reinterpret_cast(this->dh); + const uint16_t messageLen = getDNSPacketLength(message, this->len); + const uint16_t tailLen = tail.size(); + if (tailLen > (this->size - messageLen)) { + return false; + } + + /* Update length and copy data from the Lua string. */ + this->len = messageLen + tailLen; + if(tailLen > 0) { + tail.copy(message + messageLen, tailLen); + } + return true; +} + void doLatencyStats(double udiff) { if(udiff < 1000) ++g_stats.latency0_1; @@ -1031,34 +1055,41 @@ NumberedServerVector getDownstreamCandidates(const pools_t& pools, const std::st return pool->getServers(); } -static void spoofResponseFromString(DNSQuestion& dq, const string& spoofContent) +static void spoofResponseFromString(DNSQuestion& dq, const string& spoofContent, bool raw) { string result; - std::vector addrs; - stringtok(addrs, spoofContent, " ,"); + if (raw) { + SpoofAction sa(spoofContent); + sa(&dq, &result); + } + else { + std::vector addrs; + stringtok(addrs, spoofContent, " ,"); - if (addrs.size() == 1) { - try { - ComboAddress spoofAddr(spoofContent); - SpoofAction sa({spoofAddr}); - sa(&dq, &result); - } - catch(const PDNSException &e) { - SpoofAction sa(spoofContent); // CNAME then - sa(&dq, &result); - } - } else { - std::vector cas; - for (const auto& addr : addrs) { + if (addrs.size() == 1) { try { - cas.push_back(ComboAddress(addr)); + ComboAddress spoofAddr(spoofContent); + SpoofAction sa({spoofAddr}); + sa(&dq, &result); } - catch (...) { + catch(const PDNSException &e) { + DNSName cname(spoofContent); + SpoofAction sa(cname); // CNAME then + sa(&dq, &result); } + } else { + std::vector cas; + for (const auto& addr : addrs) { + try { + cas.push_back(ComboAddress(addr)); + } + catch (...) { + } + } + SpoofAction sa(cas); + sa(&dq, &result); } - SpoofAction sa(cas); - sa(&dq, &result); } } @@ -1092,7 +1123,11 @@ bool processRulesResult(const DNSAction::Action& action, DNSQuestion& dq, std::s return true; break; case DNSAction::Action::Spoof: - spoofResponseFromString(dq, ruleresult); + spoofResponseFromString(dq, ruleresult, false); + return true; + break; + case DNSAction::Action::SpoofRaw: + spoofResponseFromString(dq, ruleresult, true); return true; break; case DNSAction::Action::Truncate: @@ -1525,7 +1560,7 @@ ProcessQueryResult processQuery(DNSQuestion& dq, ClientState& cs, LocalHolders& } } - if (!handleEDNSClientSubnet(dq, &(dq.ednsAdded), &(dq.ecsAdded), g_preserveTrailingData)) { + if (!handleEDNSClientSubnet(dq, dq.ednsAdded, dq.ecsAdded, g_preserveTrailingData)) { vinfolog("Dropping query from %s because we couldn't insert the ECS value", dq.remote->toStringWithPort()); return ProcessQueryResult::Drop; } @@ -2579,8 +2614,8 @@ try } #endif - uid_t newgid=0; - gid_t newuid=0; + uid_t newgid=getegid(); + gid_t newuid=geteuid(); if(!g_cmdLine.gid.empty()) newgid = strToGID(g_cmdLine.gid.c_str()); @@ -2588,8 +2623,22 @@ try if(!g_cmdLine.uid.empty()) newuid = strToUID(g_cmdLine.uid.c_str()); - dropGroupPrivs(newgid); - dropUserPrivs(newuid); + if (getegid() != newgid) { + if (running_in_service_mgr()) { + errlog("--gid/-g set on command-line, but dnsdist was started as a systemd service. Use the 'Group' setting in the systemd unit file to set the group to run as"); + _exit(EXIT_FAILURE); + } + dropGroupPrivs(newgid); + } + + if (geteuid() != newuid) { + if (running_in_service_mgr()) { + errlog("--uid/-u set on command-line, but dnsdist was started as a systemd service. Use the 'User' setting in the systemd unit file to set the user to run as"); + _exit(EXIT_FAILURE); + } + dropUserPrivs(newuid); + } + try { /* we might still have capabilities remaining, for example if we have been started as root