From ddb970dd670bcd905c8f34458f8fcf70e9fd89bd Mon Sep 17 00:00:00 2001 From: brain Date: Mon, 19 Feb 2007 08:38:26 +0000 Subject: 1) Fix for nickname overruled with new cullList stuff -- we have to change their nick, its not safe to quit them as it messes up the nick hash. 2) Add a mute flag for users, so we can drop commands from users who have been placed on the cullList. This is independent of the actual cullList and can be used as a general mute flag e.g. by shun modules. 3) Fix /kill to also not quit the user immediately, remove need for CMD_USER_DELETED return anywhere in the code. *** THIS NEEDS TESTING BY QA *** git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@6596 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/modules.h | 2 +- include/users.h | 8 ++++++++ src/cmd_kill.cpp | 22 ++-------------------- src/cmd_nick.cpp | 16 ++++++++-------- src/cmd_quit.cpp | 2 +- src/command_parse.cpp | 18 ++++++++---------- src/userprocess.cpp | 2 ++ src/users.cpp | 9 ++++++++- 8 files changed, 38 insertions(+), 41 deletions(-) diff --git a/include/modules.h b/include/modules.h index 24a1be91f..473f84547 100644 --- a/include/modules.h +++ b/include/modules.h @@ -75,7 +75,7 @@ enum MessageType { * ipv4 servers, so this value will be ten times as * high on ipv6 servers. */ -#define NATIVE_API_VERSION 11013 +#define NATIVE_API_VERSION 11014 #ifdef IPV6 #define API_VERSION (NATIVE_API_VERSION * 10) #else diff --git a/include/users.h b/include/users.h index 1cdd53e80..d6d6fe0ab 100644 --- a/include/users.h +++ b/include/users.h @@ -414,6 +414,14 @@ class userrec : public connection */ long threshold; + /** If this is set to true, then all read operations for the user + * are dropped into the bit-bucket. + * This is used by the global CullList, but please note that setting this value + * alone will NOT cause the user to quit. This means it can be used seperately, + * for example by shun modules etc. + */ + bool muted; + /** IPV4 or IPV6 ip address. Use SetSockAddr to set this and GetProtocolFamily/ * GetIPString/GetPort to obtain its values. */ diff --git a/src/cmd_kill.cpp b/src/cmd_kill.cpp index d0de52b8d..ae327166d 100644 --- a/src/cmd_kill.cpp +++ b/src/cmd_kill.cpp @@ -50,23 +50,7 @@ CmdResult cmd_kill::Handle (const char** parameters, int pcnt, userrec *user) u->WriteCommonExcept("QUIT :%s", killreason); FOREACH_MOD(I_OnRemoteKill, OnRemoteKill(user, u, killreason)); - user_hash::iterator iter = ServerInstance->clientlist->find(u->nick); - - if (iter != ServerInstance->clientlist->end()) - ServerInstance->clientlist->erase(iter); - - if (u->registered == REG_ALL) - { - u->PurgeEmptyChannels(); - } - - if (u == user) - { - std::string original_command = std::string("KILL ") + u->nick + " :"+parameters[1]; - FOREACH_MOD(I_OnPostCommand,OnPostCommand("KILL", parameters, pcnt, user, CMD_SUCCESS,original_command)); - return CMD_USER_DELETED; - } - DELETE(u); + userrec::QuitUser(ServerInstance, u, parameters[1]); } else { @@ -75,10 +59,8 @@ CmdResult cmd_kill::Handle (const char** parameters, int pcnt, userrec *user) user->WriteTo(u, "KILL %s :%s!%s!%s (%s)", u->nick, ServerInstance->Config->ServerName, user->dhost, user->nick, parameters[1]); ServerInstance->SNO->WriteToSnoMask('k',"Local Kill by %s: %s!%s@%s (%s)", user->nick, u->nick, u->ident, u->host, parameters[1]); snprintf(killreason,MAXQUIT,"Killed (%s (%s))", user->nick, parameters[1]); - userrec::QuitUser(ServerInstance, u, killreason); - if (u == user) - return CMD_USER_DELETED; + userrec::QuitUser(ServerInstance, u, killreason); } } else diff --git a/src/cmd_nick.cpp b/src/cmd_nick.cpp index ae02a2e6d..03bad2579 100644 --- a/src/cmd_nick.cpp +++ b/src/cmd_nick.cpp @@ -69,17 +69,17 @@ CmdResult cmd_nick::Handle (const char** parameters, int pcnt, userrec *user) if ((ServerInstance->FindNick(parameters[0])) && (ServerInstance->FindNick(parameters[0]) != user) && (ServerInstance->IsNick(parameters[0]))) { userrec* InUse = ServerInstance->FindNick(parameters[0]); - /* XXX FIXME: This no longer works with the global culllist stuff, - * because the user is pushed onto the cullList then we accept a new user - * with the SAME nickname, so this mucks up the nickname hash completely. - * We need to find a way to force a nickchange upon the user whos being - * overruled, rather than quitting them. -- Brain - * if (InUse->registered != REG_ALL) { - userrec::QuitUser(ServerInstance, InUse, "Nickname overruled"); + /* change the nick of the older user to nnn-overruled, + * where nnn is their file descriptor. We know this to be unique. + */ + std::string changeback = ConvToStr(InUse->fd) + "-overruled"; + InUse->UpdateNickHash(changeback.c_str()); + strlcpy(InUse->nick, changeback.c_str(), NICKMAX - 1); + InUse->InvalidateCache(); } - else*/ + else { user->WriteServ("433 %s %s :Nickname is already in use.", user->registered >= REG_NICK ? user->nick : "*", parameters[0]); return CMD_FAILURE; diff --git a/src/cmd_quit.cpp b/src/cmd_quit.cpp index 2498d4209..bb328de5b 100644 --- a/src/cmd_quit.cpp +++ b/src/cmd_quit.cpp @@ -27,6 +27,6 @@ extern "C" command_t* init_command(InspIRCd* Instance) CmdResult cmd_quit::Handle (const char** parameters, int pcnt, userrec *user) { userrec::QuitUser(ServerInstance, user, pcnt ? parameters[0] : "Client exited"); - return CMD_USER_DELETED; + return CMD_SUCCESS; } diff --git a/src/command_parse.cpp b/src/command_parse.cpp index 259d636d3..f84df3342 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -153,8 +153,7 @@ int CommandParser::LoopCall(userrec* user, command_t* CommandObj, const char** p new_parameters[splithere] = item.c_str(); new_parameters[extra] = extrastuff.c_str(); - if (CommandObj->Handle(new_parameters,pcnt,user) == CMD_USER_DELETED) - return 1; + CommandObj->Handle(new_parameters,pcnt,user); dupes[item.c_str()] = true; } @@ -198,8 +197,7 @@ int CommandParser::LoopCall(userrec* user, command_t* CommandObj, const char** p * record out from under us (e.g. if we /kill a comma sep list, and we're * in that list ourselves) abort if we're gone. */ - if (CommandObj->Handle(new_parameters,pcnt,user) == CMD_USER_DELETED) - return 1; + CommandObj->Handle(new_parameters,pcnt,user); dupes[item.c_str()] = true; } @@ -344,10 +342,7 @@ void CommandParser::ProcessCommand(userrec *user, std::string &cmd) */ CmdResult result = cm->second->Handle(command_p,items,user); - if (result != CMD_USER_DELETED) - { - FOREACH_MOD(I_OnPostCommand,OnPostCommand(command, command_p, items, user, result,cmd)); - } + FOREACH_MOD(I_OnPostCommand,OnPostCommand(command, command_p, items, user, result,cmd)); return; } else @@ -407,8 +402,11 @@ void CommandParser::ProcessBuffer(std::string &buffer,userrec *user) if (buffer.length()) { - ServerInstance->Log(DEBUG,"-> :%s %s",user->nick,buffer.c_str()); - this->ProcessCommand(user,buffer); + if (!user->muted) + { + ServerInstance->Log(DEBUG,"-> :%s %s",user->nick,buffer.c_str()); + this->ProcessCommand(user,buffer); + } } } diff --git a/src/userprocess.cpp b/src/userprocess.cpp index fded4a5e3..1d2187165 100644 --- a/src/userprocess.cpp +++ b/src/userprocess.cpp @@ -249,6 +249,7 @@ void InspIRCd::DoBackgroundUserStuff(time_t TIME) */ if ((TIME > curr->timeout) && (curr->registered != REG_ALL)) { + curr->muted = true; GlobalCulls.AddItem(curr,"Registration timeout"); continue; } @@ -296,6 +297,7 @@ void InspIRCd::DoBackgroundUserStuff(time_t TIME) /* Everybody loves boobies. */ time_t time = this->Time(false) - (curr->nping - curr->pingmax); std::string boobies = "Ping timeout: " + ConvToStr(time) + " second" + (time > 1 ? "s" : ""); + curr->muted = true; GlobalCulls.AddItem(curr, boobies); curr->lastping = 1; curr->nping = TIME+curr->pingmax; diff --git a/src/users.cpp b/src/users.cpp index 55aa7c1ed..6398603d9 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -319,7 +319,7 @@ userrec::userrec(InspIRCd* Instance) : ServerInstance(Instance) age = ServerInstance->Time(true); lines_in = lastping = signon = idle_lastmsg = nping = registered = 0; ChannelCount = timeout = flood = bytes_in = bytes_out = cmds_in = cmds_out = 0; - exempt = haspassed = dns_done = false; + muted = exempt = haspassed = dns_done = false; fd = -1; recvq = ""; sendq = ""; @@ -802,6 +802,7 @@ void userrec::UnOper() void userrec::QuitUser(InspIRCd* Instance, userrec *user, const std::string &quitreason) { + user->muted = true; Instance->GlobalCulls.AddItem(user, quitreason.c_str()); } @@ -972,24 +973,28 @@ void userrec::FullConnect() if ((!a) || (a->GetType() == CC_DENY)) { + this->muted = true; ServerInstance->GlobalCulls.AddItem(this,"Unauthorised connection"); return; } if ((!a->GetPass().empty()) && (!this->haspassed)) { + this->muted = true; ServerInstance->GlobalCulls.AddItem(this,"Invalid password"); return; } if (this->LocalCloneCount() > a->GetMaxLocal()) { + this->muted = true; ServerInstance->GlobalCulls.AddItem(this, "No more connections allowed from your host via this connect class (local)"); ServerInstance->WriteOpers("*** WARNING: maximum LOCAL connections (%ld) exceeded for IP %s", a->GetMaxLocal(), this->GetIPString()); return; } else if (this->GlobalCloneCount() > a->GetMaxGlobal()) { + this->muted = true; ServerInstance->GlobalCulls.AddItem(this, "No more connections allowed from your host via this connect class (global)"); ServerInstance->WriteOpers("*** WARNING: maximum GLOBAL connections (%ld) exceeded for IP %s",a->GetMaxGlobal(), this->GetIPString()); return; @@ -1001,6 +1006,7 @@ void userrec::FullConnect() if (r) { + this->muted = true; char reason[MAXBUF]; snprintf(reason,MAXBUF,"G-Lined: %s",r->reason); ServerInstance->GlobalCulls.AddItem(this, reason); @@ -1011,6 +1017,7 @@ void userrec::FullConnect() if (n) { + this->muted = true; char reason[MAXBUF]; snprintf(reason,MAXBUF,"K-Lined: %s",n->reason); ServerInstance->GlobalCulls.AddItem(this, reason); -- cgit v1.2.3