X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fusers.cpp;h=2ee389c86ff36b5abb69ad005c61fde720b3515a;hb=663f0620bea4dc1e64ec640992f4d511ae1ef97b;hp=81f83058387fc544245ec01bbb1d4395c9da344c;hpb=61197974c5f7ce009096468b208c3abf2c25810b;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/users.cpp b/src/users.cpp index 81f830583..2ee389c86 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -1,16 +1,28 @@ -/* +------------------------------------+ - * | Inspire Internet Relay Chat Daemon | - * +------------------------------------+ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2009-2010 Daniel De Graaf + * Copyright (C) 2006-2009 Robin Burchell + * Copyright (C) 2006-2007, 2009 Dennis Friis + * Copyright (C) 2008 John Brooks + * Copyright (C) 2008 Thomas Stagner + * Copyright (C) 2008 Oliver Lupton + * Copyright (C) 2003-2008 Craig Edwards * - * InspIRCd: (C) 2002-2010 InspIRCd Development Team - * See: http://wiki.inspircd.org/Credits + * 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 + * License as published by the Free Software Foundation, version 2. * - * This program is free but copyrighted software; see - * the file COPYING for details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. * - * --------------------------------------------------- + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + #include "inspircd.h" #include #include "socketengine.h" @@ -113,6 +125,8 @@ void LocalUser::StartDNSLookup() catch (CoreException& e) { ServerInstance->Logs->Log("USERS", DEBUG,"Error in resolver: %s",e.GetReason()); + dns_done = true; + ServerInstance->stats->statsDnsBad++; } } @@ -191,6 +205,7 @@ User::User(const std::string &uid, const std::string& sid, int type) signon = idle_lastmsg = 0; registered = 0; quietquit = quitting = exempt = dns_done = false; + quitting_sendq = false; client_sa.sa.sa_family = AF_UNSPEC; ServerInstance->Logs->Log("USERS", DEBUG, "New UUID for user: %s", uuid.c_str()); @@ -511,25 +526,19 @@ eol_found: if (user->quitting) return; } - // Add pseudo-penalty so that we continue processing after sendq recedes - if (user->CommandFloodPenalty == 0 && getSendQSize() >= sendqmax) - user->CommandFloodPenalty++; if (user->CommandFloodPenalty >= penaltymax && !user->MyClass->fakelag) ServerInstance->Users->QuitUser(user, "Excess Flood"); } void UserIOHandler::AddWriteBuf(const std::string &data) { + if (user->quitting_sendq) + return; if (!user->quitting && getSendQSize() + data.length() > user->MyClass->GetSendqHardMax() && !user->HasPrivPermission("users/flood/increased-buffers")) { - /* - * Quit the user FIRST, because otherwise we could recurse - * here and hit the same limit. - */ - ServerInstance->Users->QuitUser(user, "SendQ exceeded"); - ServerInstance->SNO->WriteToSnoMask('a', "User %s SendQ exceeds connect class maximum of %lu", - user->nick.c_str(), user->MyClass->GetSendqHardMax()); + user->quitting_sendq = true; + ServerInstance->GlobalCulls.AddSQItem(user); return; } @@ -649,7 +658,7 @@ void OperInfo::init() { this->AllowedUserModes.set(); } - else + else if (*c >= 'A' && *c < 'z') { this->AllowedUserModes[*c - 'A'] = true; } @@ -661,7 +670,7 @@ void OperInfo::init() { this->AllowedChanModes.set(); } - else + else if (*c >= 'A' && *c < 'z') { this->AllowedChanModes[*c - 'A'] = true; } @@ -727,6 +736,7 @@ void LocalUser::CheckClass() if (!a) { ServerInstance->Users->QuitUser(this, "Access denied by configuration"); + return; } else if (a->type == CC_DENY) { @@ -736,13 +746,15 @@ void LocalUser::CheckClass() else if ((a->GetMaxLocal()) && (ServerInstance->Users->LocalCloneCount(this) > a->GetMaxLocal())) { ServerInstance->Users->QuitUser(this, "No more connections allowed from your host via this connect class (local)"); - ServerInstance->SNO->WriteToSnoMask('a', "WARNING: maximum LOCAL connections (%ld) exceeded for IP %s", a->GetMaxLocal(), this->GetIPString()); + if (a->maxconnwarn) + ServerInstance->SNO->WriteToSnoMask('a', "WARNING: maximum LOCAL connections (%ld) exceeded for IP %s", a->GetMaxLocal(), this->GetIPString()); return; } else if ((a->GetMaxGlobal()) && (ServerInstance->Users->GlobalCloneCount(this) > a->GetMaxGlobal())) { ServerInstance->Users->QuitUser(this, "No more connections allowed from your host via this connect class (global)"); - ServerInstance->SNO->WriteToSnoMask('a', "WARNING: maximum GLOBAL connections (%ld) exceeded for IP %s", a->GetMaxGlobal(), this->GetIPString()); + if (a->maxconnwarn) + ServerInstance->SNO->WriteToSnoMask('a', "WARNING: maximum GLOBAL connections (%ld) exceeded for IP %s", a->GetMaxGlobal(), this->GetIPString()); return; } @@ -781,6 +793,7 @@ void LocalUser::FullConnect() * may put the user into a totally seperate class with different restrictions! so we *must* check again. * Don't remove this! -- w00t */ + MyClass = NULL; SetClass(); CheckClass(); CheckLines(); @@ -815,6 +828,9 @@ void LocalUser::FullConnect() if (!MOD_RESULT) ServerInstance->CallCommandHandler(command, parameters, this); + if (ServerInstance->Config->RawLog) + WriteServ("PRIVMSG %s :*** Raw I/O logging is enabled on this server. All messages, passwords, and commands are being recorded.", nick.c_str()); + /* * We don't set REG_ALL until triggering OnUserConnect, so some module events don't spew out stuff * for a user that doesn't exist yet. @@ -825,10 +841,12 @@ void LocalUser::FullConnect() FOREACH_MOD(I_OnPostConnect,OnPostConnect(this)); - ServerInstance->SNO->WriteToSnoMask('c',"Client connecting on port %d: %s!%s@%s [%s] [%s]", - this->GetServerPort(), this->nick.c_str(), this->ident.c_str(), this->host.c_str(), this->GetIPString(), this->fullname.c_str()); + ServerInstance->SNO->WriteToSnoMask('c',"Client connecting on port %d (class %s): %s!%s@%s [%s] [%s]", + this->GetServerPort(), this->MyClass->name.c_str(), this->nick.c_str(), this->ident.c_str(), this->host.c_str(), this->GetIPString(), this->fullname.c_str()); ServerInstance->Logs->Log("BANCACHE", DEBUG, "BanCache: Adding NEGATIVE hit for %s", this->GetIPString()); ServerInstance->BanCache->AddHit(this->GetIPString(), "", ""); + // reset the flood penalty (which could have been raised due to things like auto +x) + CommandFloodPenalty = 0; } void User::InvalidateCache() @@ -1019,7 +1037,7 @@ void LocalUser::Write(const std::string& text) return; } - ServerInstance->Logs->Log("USEROUTPUT", DEBUG,"C[%s] O %s", uuid.c_str(), text.c_str()); + ServerInstance->Logs->Log("USEROUTPUT", RAWIO, "C[%s] O %s", uuid.c_str(), text.c_str()); eh.AddWriteBuf(text); eh.AddWriteBuf(wide_newline); @@ -1392,7 +1410,9 @@ void User::DoHostCycle(const std::string &quitline) { for(unsigned int i=0; i < memb->modes.length(); i++) modeline.append(" ").append(nick); - snprintf(buffer, MAXBUF, ":%s MODE %s +%s", GetFullHost().c_str(), c->name.c_str(), modeline.c_str()); + snprintf(buffer, MAXBUF, ":%s MODE %s +%s", + ServerInstance->Config->CycleHostsFromUser ? GetFullHost().c_str() : ServerInstance->Config->ServerName.c_str(), + c->name.c_str(), modeline.c_str()); modeline = buffer; } @@ -1533,7 +1553,7 @@ void User::SplitChanList(User* dest, const std::string &cl) } } - if (line.length()) + if (line.length() != prefix.str().length()) { ServerInstance->SendWhoisLine(this, dest, 319, "%s", line.c_str()); } @@ -1591,7 +1611,7 @@ void LocalUser::SetClass(const std::string &explicit_name) continue; /* check if host matches.. */ - if (c->GetHost().length() && !InspIRCd::MatchCIDR(this->GetIPString(), c->GetHost(), NULL) && + if (!InspIRCd::MatchCIDR(this->GetIPString(), c->GetHost(), NULL) && !InspIRCd::MatchCIDR(this->host, c->GetHost(), NULL)) { ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "No host match (for %s)", c->GetHost().c_str()); @@ -1619,9 +1639,9 @@ void LocalUser::SetClass(const std::string &explicit_name) continue; } - if (!c->config->getString("pass").empty()) + if (regdone && !c->config->getString("password").empty()) { - if (ServerInstance->PassCompare(this, c->config->getString("pass"), password, c->config->getString("hash"))) + if (ServerInstance->PassCompare(this, c->config->getString("password"), password, c->config->getString("hash"))) { ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Bad password, skipping"); continue; @@ -1687,7 +1707,7 @@ const std::string& FakeUser::GetFullRealHost() ConnectClass::ConnectClass(ConfigTag* tag, char t, const std::string& mask) : config(tag), type(t), fakelag(true), name("unnamed"), registration_timeout(0), host(mask), pingtime(0), softsendqmax(0), hardsendqmax(0), recvqmax(0), - penaltythreshold(0), commandrate(0), maxlocal(0), maxglobal(0), maxchans(0), limit(0) + penaltythreshold(0), commandrate(0), maxlocal(0), maxglobal(0), maxconnwarn(true), maxchans(0), limit(0) { } @@ -1696,13 +1716,16 @@ ConnectClass::ConnectClass(ConfigTag* tag, char t, const std::string& mask, cons registration_timeout(parent.registration_timeout), host(mask), pingtime(parent.pingtime), softsendqmax(parent.softsendqmax), hardsendqmax(parent.hardsendqmax), recvqmax(parent.recvqmax), penaltythreshold(parent.penaltythreshold), commandrate(parent.commandrate), - maxlocal(parent.maxlocal), maxglobal(parent.maxglobal), maxchans(parent.maxchans), + maxlocal(parent.maxlocal), maxglobal(parent.maxglobal), maxconnwarn(parent.maxconnwarn), maxchans(parent.maxchans), limit(parent.limit) { } void ConnectClass::Update(const ConnectClass* src) { + config = src->config; + type = src->type; + fakelag = src->fakelag; name = src->name; registration_timeout = src->registration_timeout; host = src->host; @@ -1711,7 +1734,10 @@ void ConnectClass::Update(const ConnectClass* src) hardsendqmax = src->hardsendqmax; recvqmax = src->recvqmax; penaltythreshold = src->penaltythreshold; + commandrate = src->commandrate; maxlocal = src->maxlocal; maxglobal = src->maxglobal; + maxconnwarn = src->maxconnwarn; + maxchans = src->maxchans; limit = src->limit; }