X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fcommands%2Fcmd_nick.cpp;h=bdaff8723d62364ba66323762d44a155db613022;hb=6d03943426dcce76ba66567a9b18425a5ebb4c0c;hp=0e24037528a6f2730d59ee36b4200f0de63a1587;hpb=3798e67d95a44e50ce55b0bd25dc693aca56f318;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/commands/cmd_nick.cpp b/src/commands/cmd_nick.cpp index 0e2403752..bdaff8723 100644 --- a/src/commands/cmd_nick.cpp +++ b/src/commands/cmd_nick.cpp @@ -2,8 +2,8 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * InspIRCd: (C) 2002-2008 InspIRCd Development Team - * See: http://www.inspircd.org/wiki/index.php/Credits + * InspIRCd: (C) 2002-2009 InspIRCd Development Team + * See: http://wiki.inspircd.org/Credits * * This program is free but copyrighted software; see * the file COPYING for details. @@ -13,12 +13,26 @@ #include "inspircd.h" #include "xline.h" -#include "commands/cmd_nick.h" -extern "C" DllExport Command* init_command(InspIRCd* Instance) +/** Handle /NICK. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class CommandNick : public Command { - return new CommandNick(Instance); -} + public: + /** Constructor for nick. + */ + CommandNick ( Module* parent) : Command(parent,"NICK", 1, 1) { works_before_reg = true; syntax = ""; Penalty = 3; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const std::vector& parameters, User *user); +}; /** Handle nick changes from users. * NOTE: If you are used to ircds based on ircd2.8, and are looking @@ -38,17 +52,16 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User if (((!ServerInstance->IsNick(parameters[0].c_str(), ServerInstance->Config->Limits.NickMax))) && (IS_LOCAL(user))) { - if (!allowinvalid) + if (!User::NICKForced.get(user)) { if (parameters[0] == "0") { // Special case, Fake a /nick UIDHERE. Useful for evading "ERR: NICK IN USE" on connect etc. std::vector p2; - std::deque dummy; p2.push_back(user->uuid); - this->HandleInternal(1, dummy); + User::NICKForced.set(user, 1); this->Handle(p2, user); - this->HandleInternal(0, dummy); + User::NICKForced.set(user, 0); return CMD_SUCCESS; } @@ -69,14 +82,14 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User * able to do silly things like this even though the RFC says * the nick AAA is the same as the nick aaa. */ - oldnick.assign(user->nick, 0, ServerInstance->Config->Limits.NickMax); - int MOD_RESULT = 0; - FOREACH_RESULT(I_OnUserPreNick,OnUserPreNick(user,parameters[0])); - if (MOD_RESULT) + oldnick.assign(user->nick, 0, IS_LOCAL(user) ? ServerInstance->Config->Limits.NickMax : MAXBUF); + ModResult MOD_RESULT; + FIRST_MOD_RESULT(OnUserPreNick, MOD_RESULT, (user,parameters[0])); + if (MOD_RESULT == MOD_RES_DENY) return CMD_FAILURE; if (user->registered == REG_ALL) user->WriteCommon("NICK %s",parameters[0].c_str()); - user->nick.assign(parameters[0], 0, ServerInstance->Config->Limits.NickMax); + user->nick.assign(parameters[0], 0, IS_LOCAL(user) ? ServerInstance->Config->Limits.NickMax : MAXBUF); user->InvalidateCache(); FOREACH_MOD(I_OnUserPostNick,OnUserPostNick(user,oldnick)); return CMD_SUCCESS; @@ -91,15 +104,32 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User * Also don't check Q:Lines for remote nickchanges, they should have our Q:Lines anyway to enforce themselves. * -- w00t */ - if (!allowinvalid || !IS_LOCAL(user)) + if (!IS_LOCAL(user)) { XLine* mq = ServerInstance->XLines->MatchesLine("Q",parameters[0]); if (mq) { - ServerInstance->SNO->WriteToSnoMask('x', "Q-Lined nickname %s from %s!%s@%s: %s", parameters[0].c_str(), user->nick.c_str(), user->ident.c_str(), user->host.c_str(), mq->reason); - user->WriteNumeric(432, "%s %s :Invalid nickname: %s",user->nick.c_str(), parameters[0].c_str(), mq->reason); + if (user->registered == REG_ALL) + { + ServerInstance->SNO->WriteGlobalSno('a', "Q-Lined nickname %s from %s!%s@%s: %s", + parameters[0].c_str(), user->nick.c_str(), user->ident.c_str(), user->host.c_str(), mq->reason.c_str()); + } + user->WriteNumeric(432, "%s %s :Invalid nickname: %s",user->nick.c_str(), parameters[0].c_str(), mq->reason.c_str()); return CMD_FAILURE; } + + if (ServerInstance->Config->RestrictBannedUsers) + { + for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++) + { + Channel *chan = *i; + if (chan->GetPrefixValue(user) < VOICE_VALUE && chan->IsBanned(user)) + { + user->WriteNumeric(404, "%s %s :Cannot send to channel (you're banned)", user->nick.c_str(), chan->name.c_str()); + return CMD_FAILURE; + } + } + } } /* @@ -120,7 +150,7 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User InUse->WriteTo(InUse, "NICK %s", InUse->uuid.c_str()); InUse->WriteNumeric(433, "%s %s :Nickname overruled.", InUse->nick.c_str(), InUse->nick.c_str()); InUse->UpdateNickHash(InUse->uuid.c_str()); - InUse->nick.assign(InUse->uuid, 0, ServerInstance->Config->Limits.NickMax); + InUse->nick.assign(InUse->uuid, 0, IS_LOCAL(InUse) ? ServerInstance->Config->Limits.NickMax : MAXBUF); InUse->InvalidateCache(); InUse->registered &= ~REG_NICK; } @@ -134,16 +164,16 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User } - int MOD_RESULT = 0; - FOREACH_RESULT(I_OnUserPreNick,OnUserPreNick(user, parameters[0])); - if (MOD_RESULT) + ModResult MOD_RESULT; + FIRST_MOD_RESULT(OnUserPreNick, MOD_RESULT, (user, parameters[0])); + if (MOD_RESULT == MOD_RES_DENY) // if a module returns true, the nick change is silently forbidden. return CMD_FAILURE; if (user->registered == REG_ALL) user->WriteCommon("NICK %s", parameters[0].c_str()); - oldnick.assign(user->nick, 0, ServerInstance->Config->Limits.NickMax); + oldnick.assign(user->nick, 0, IS_LOCAL(user) ? ServerInstance->Config->Limits.NickMax : MAXBUF); /* change the nick of the user in the users_hash */ user = user->UpdateNickHash(parameters[0].c_str()); @@ -152,34 +182,25 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User if (!user) return CMD_FAILURE; - user->nick.assign(parameters[0], 0, ServerInstance->Config->Limits.NickMax); + user->nick.assign(parameters[0], 0, IS_LOCAL(user) ? ServerInstance->Config->Limits.NickMax : MAXBUF); user->InvalidateCache(); - /* Update display nicks */ - for (UCListIter v = user->chans.begin(); v != user->chans.end(); v++) - { - CUList* ulist = v->first->GetUsers(); - CUList::iterator i = ulist->find(user); - if (i != ulist->end()) - i->second = user->nick; - } - if (user->registered < REG_NICKUSER) { user->registered = (user->registered | REG_NICK); - } - - // Keep these seperate! + if (user->registered == REG_NICKUSER) + { + /* user is registered now, bit 0 = USER command, bit 1 = sent a NICK command */ + FIRST_MOD_RESULT(OnUserRegister, MOD_RESULT, (user)); + if (MOD_RESULT == MOD_RES_DENY) + return CMD_FAILURE; - if (user->registered == REG_NICKUSER) - { - /* user is registered now, bit 0 = USER command, bit 1 = sent a NICK command */ - MOD_RESULT = 0; - FOREACH_RESULT(I_OnUserRegister,OnUserRegister(user)); - if (MOD_RESULT > 0) - return CMD_FAILURE; + // return early to not penalize new users + return CMD_SUCCESS; + } } - else if (user->registered == REG_ALL) + + if (user->registered == REG_ALL) { user->IncreasePenalty(10); FOREACH_MOD(I_OnUserPostNick,OnUserPostNick(user, oldnick)); @@ -189,9 +210,5 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User } -CmdResult CommandNick::HandleInternal(const unsigned int id, const std::deque&) -{ - allowinvalid = (id != 0); - return CMD_SUCCESS; -} +COMMAND_INIT(CommandNick)