X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fxline.cpp;h=04ac67f684d1ff2cd2ace35d371b39257589cd49;hb=ab49ff82c562a0a97bcca759f6a6c80fef31516f;hp=55496b42405e73d373bb2ff160c672c5ba1394c7;hpb=f2e3fd5952b23209b084bde4f464e6643c8a00ff;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/xline.cpp b/src/xline.cpp index 55496b424..04ac67f68 100644 --- a/src/xline.cpp +++ b/src/xline.cpp @@ -1,11 +1,16 @@ /* * InspIRCd -- Internet Relay Chat Daemon * + * Copyright (C) 2019 Matt Schatz + * Copyright (C) 2013, 2017-2019 Sadie Powell + * Copyright (C) 2013 Adam + * Copyright (C) 2012-2014, 2016 Attila Molnar + * Copyright (C) 2012, 2018-2019 Robby + * Copyright (C) 2009 Uli Schlachter * Copyright (C) 2009 Daniel De Graaf - * Copyright (C) 2005-2009 Robin Burchell - * Copyright (C) 2004-2008 Craig Edwards + * Copyright (C) 2007-2009 Robin Burchell * Copyright (C) 2007 Dennis Friis - * Copyright (C) 2007 John Brooks + * Copyright (C) 2006-2008, 2010 Craig Edwards * * This file is part of InspIRCd. InspIRCd is free software: you can * redistribute it and/or modify it under the terms of the GNU General Public @@ -265,12 +270,31 @@ bool XLineManager::AddLine(XLine* line, User* user) LookupIter i = x->second.find(line->Displayable()); if (i != x->second.end()) { - // XLine propagation bug was here, if the line to be added already exists and - // it's expired then expire it and add the new one instead of returning false - if ((!i->second->duration) || (ServerInstance->Time() < i->second->expiry)) - return false; + bool silent = false; - ExpireLine(x, i); + // Allow replacing a config line for an updated config line. + if (i->second->from_config && line->from_config) + { + // Nothing changed, skip adding this one. + if (i->second->reason == line->reason) + return false; + + silent = true; + } + // Allow replacing a non-config line for a new config line. + else if (!line->from_config) + { + // X-line propagation bug was here, if the line to be added already exists and + // it's expired then expire it and add the new one instead of returning false + if ((!i->second->duration) || (ServerInstance->Time() < i->second->expiry)) + return false; + } + else + { + silent = true; + } + + ExpireLine(x, i, silent); } } @@ -294,7 +318,7 @@ bool XLineManager::AddLine(XLine* line, User* user) // deletes a line, returns true if the line existed and was removed -bool XLineManager::DelLine(const char* hostmask, const std::string &type, User* user, bool simulate) +bool XLineManager::DelLine(const char* hostmask, const std::string& type, std::string& reason, User* user, bool simulate) { ContainerIter x = lookup_lines.find(type); @@ -306,6 +330,8 @@ bool XLineManager::DelLine(const char* hostmask, const std::string &type, User* if (y == x->second.end()) return false; + reason.assign(y->second->reason); + if (simulate) return true; @@ -401,11 +427,13 @@ XLine* XLineManager::MatchesLine(const std::string &type, const std::string &pat } // removes lines that have expired -void XLineManager::ExpireLine(ContainerIter container, LookupIter item) +void XLineManager::ExpireLine(ContainerIter container, LookupIter item, bool silent) { FOREACH_MOD(OnExpireLine, (item->second)); - item->second->DisplayExpiry(); + if (!silent) + item->second->DisplayExpiry(); + item->second->Unset(); /* TODO: Can we skip this loop by having a 'pending' field in the XLine class, which is set when a line @@ -423,9 +451,9 @@ void XLineManager::ExpireLine(ContainerIter container, LookupIter item) void XLineManager::ApplyLines() { const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers(); - for (UserManager::LocalList::const_iterator j = list.begin(); j != list.end(); ++j) + for (UserManager::LocalList::const_iterator j = list.begin(); j != list.end(); ) { - LocalUser* u = *j; + LocalUser* u = *j++; // Don't ban people who are exempt. if (u->exempt) @@ -435,7 +463,14 @@ void XLineManager::ApplyLines() { XLine *x = *i; if (x->Matches(u)) + { x->Apply(u); + + // If applying the X-line has killed the user then don't + // apply any more lines to them. + if (u->quitting) + break; + } } } @@ -463,13 +498,36 @@ void XLineManager::InvokeStats(const std::string& type, unsigned int numeric, St ExpireLine(n, i); } else - stats.AddRow(numeric, i->second->Displayable()+" "+ - ConvToStr(i->second->set_time)+" "+ConvToStr(i->second->duration)+" "+i->second->source+" :"+i->second->reason); + stats.AddRow(numeric, i->second->Displayable(), i->second->set_time, i->second->duration, i->second->source, i->second->reason); i = safei; } } } +bool XLineManager::InvokeStats(const std::string& type, Stats::Context& context) +{ + ContainerIter citer = lookup_lines.find(type); + if (citer == lookup_lines.end()) + return false; + + for (LookupIter liter = citer->second.begin(); liter != citer->second.end(); ) + { + // We might be about to expire the XLine so we have to increment the + // iterator early to avoid doing that causing iterator invalidation. + LookupIter current = liter++; + + XLine* xline = current->second; + if (xline->duration && xline->expiry <= ServerInstance->Time()) + { + // This XLine has expired so remove and skip it. + ExpireLine(citer, current); + continue; + } + + context.AddRow(RPL_STATS, context.GetSymbol(), xline->Displayable(), xline->set_time, xline->duration, xline->source, xline->reason); + } + return true; +} XLineManager::XLineManager() { @@ -537,7 +595,7 @@ void XLine::DefaultApply(User* u, const std::string &line, bool bancache) if (bancache) { ServerInstance->Logs->Log("BANCACHE", LOG_DEBUG, "BanCache: Adding positive hit (" + line + ") for " + u->GetIPString()); - ServerInstance->BanCache.AddHit(u->GetIPString(), this->type, banReason, this->duration); + ServerInstance->BanCache.AddHit(u->GetIPString(), this->type, banReason, (this->duration > 0 ? (this->expiry - ServerInstance->Time()) : 0)); } } @@ -680,8 +738,8 @@ void ELine::OnAdd() void XLine::DisplayExpiry() { bool onechar = (type.length() == 1); - ServerInstance->SNO->WriteToSnoMask('x', "Removing expired %s%s %s (set by %s %ld seconds ago): %s", - type.c_str(), (onechar ? "-line" : ""), Displayable().c_str(), source.c_str(), (long)(ServerInstance->Time() - set_time), reason.c_str()); + ServerInstance->SNO->WriteToSnoMask('x', "Removing expired %s%s %s (set by %s %s ago): %s", + type.c_str(), (onechar ? "-line" : ""), Displayable().c_str(), source.c_str(), InspIRCd::DurationString(ServerInstance->Time() - set_time).c_str(), reason.c_str()); } const std::string& ELine::Displayable() @@ -748,23 +806,23 @@ XLineFactory* XLineManager::GetFactory(const std::string &type) return n->second; } -void XLineManager::ClearConfigLines() +void XLineManager::ExpireRemovedConfigLines(const std::string& type, const insp::flat_set& configlines) { // Nothing to do. if (lookup_lines.empty()) return; - ServerInstance->SNO->WriteToSnoMask('x', "Server rehashing; expiring lines defined in the server config ..."); - for (ContainerIter type = lookup_lines.begin(); type != lookup_lines.end(); ++type) + ContainerIter xlines = lookup_lines.find(type); + if (xlines == lookup_lines.end()) + return; + + for (LookupIter xline = xlines->second.begin(); xline != xlines->second.end(); ) { - for (LookupIter xline = type->second.begin(); xline != type->second.end(); ) - { - // We cache this to avoid iterator invalidation. - LookupIter cachedxline = xline++; - if (cachedxline->second->from_config) - { - ExpireLine(type, cachedxline); - } - } + LookupIter cachedxline = xline++; + if (!cachedxline->second->from_config) + continue; + + if (!configlines.count(cachedxline->second->Displayable())) + ExpireLine(xlines, cachedxline); } }