]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/users.cpp
m_check: Include IP and gecos in host/IP-mask lookup results
[user/henk/code/inspircd.git] / src / users.cpp
index 2e2229afa1b9622e7f47ac9c6d6972276dd08325..2ee389c86ff36b5abb69ad005c61fde720b3515a 100644 (file)
@@ -1,16 +1,28 @@
-/*       +------------------------------------+
- *       | Inspire Internet Relay Chat Daemon |
- *       +------------------------------------+
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2006-2009 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2006-2007, 2009 Dennis Friis <peavey@inspircd.org>
+ *   Copyright (C) 2008 John Brooks <john.brooks@dereferenced.net>
+ *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ *   Copyright (C) 2008 Oliver Lupton <oliverlupton@gmail.com>
+ *   Copyright (C) 2003-2008 Craig Edwards <craigedwards@brainbox.cc>
  *
- *  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 <http://www.gnu.org/licenses/>.
  */
 
+
 #include "inspircd.h"
 #include <stdarg.h>
 #include "socketengine.h"
@@ -193,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());
@@ -513,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;
        }
 
@@ -651,7 +658,7 @@ void OperInfo::init()
                        {
                                this->AllowedUserModes.set();
                        }
-                       else
+                       else if (*c >= 'A' && *c < 'z')
                        {
                                this->AllowedUserModes[*c - 'A'] = true;
                        }
@@ -663,7 +670,7 @@ void OperInfo::init()
                        {
                                this->AllowedChanModes.set();
                        }
-                       else
+                       else if (*c >= 'A' && *c < 'z')
                        {
                                this->AllowedChanModes[*c - 'A'] = true;
                        }
@@ -739,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;
        }
 
@@ -784,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();
@@ -831,8 +841,8 @@ 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)
@@ -1543,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());
        }
@@ -1601,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());
@@ -1697,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)
 {
 }
 
@@ -1706,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;
@@ -1721,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;
 }