diff options
-rw-r--r-- | include/modules.h | 7 | ||||
-rw-r--r-- | include/users.h | 7 | ||||
-rw-r--r-- | src/cmd_nick.cpp | 2 | ||||
-rw-r--r-- | src/modules.cpp | 4 | ||||
-rw-r--r-- | src/modules/m_nicklock.cpp | 11 | ||||
-rw-r--r-- | src/modules/m_sanick.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_spanningtree.cpp | 6 | ||||
-rw-r--r-- | src/userprocess.cpp | 4 | ||||
-rw-r--r-- | src/users.cpp | 111 |
9 files changed, 71 insertions, 88 deletions
diff --git a/include/modules.h b/include/modules.h index 3b056223c..07e13eb20 100644 --- a/include/modules.h +++ b/include/modules.h @@ -1499,13 +1499,6 @@ class Server : public Extensible * user must have both modes set to receive the message. */ virtual void SendToModeMask(const std::string &modes, int flags, const std::string &text); - - /** Forces a user nickchange. - * This command works similarly to SVSNICK, and can be used to implement Q-lines etc. - * If you specify an invalid nickname, the nick change will be dropped and the target user will receive - * the error numeric for it. - */ - virtual void ChangeUserNick(userrec* user, const std::string &nickname); /** Matches text against a glob pattern. * Uses the ircd's internal matching function to match string against a globbing pattern, e.g. *!*@*.com diff --git a/include/users.h b/include/users.h index 320123e2d..bfee92f83 100644 --- a/include/users.h +++ b/include/users.h @@ -443,6 +443,10 @@ class userrec : public connection void Oper(const std::string &opertype); + void FullConnect(CullList* Goners); + userrec* UpdateNickHash(const char* New); + bool ForceNickChange(const char* newnick); + void UnOper(); /** Default destructor @@ -471,9 +475,6 @@ typedef std::map<irc::string,whowas_set*> whowas_users; void MaintainWhoWas(time_t TIME); void AddClient(int socket, int port, bool iscached, insp_inaddr ip4); -void FullConnectUser(userrec* user, CullList* Goners); -userrec* ReHashNick(const char* Old, const char* New); -void force_nickchange(userrec* user,const char* newnick); /* Configuration callbacks */ bool InitTypes(const char* tag); diff --git a/src/cmd_nick.cpp b/src/cmd_nick.cpp index b767bc32b..cdb37690e 100644 --- a/src/cmd_nick.cpp +++ b/src/cmd_nick.cpp @@ -124,7 +124,7 @@ void cmd_nick::Handle (const char** parameters, int pcnt, userrec *user) strlcpy(oldnick, user->nick, NICKMAX - 1); /* change the nick of the user in the users_hash */ - user = ReHashNick(user->nick, parameters[0]); + user = user->UpdateNickHash(parameters[0]); /* actually change the nick within the record */ if (!user) return; if (!user->nick) return; diff --git a/src/modules.cpp b/src/modules.cpp index 71dee1a59..a0e150764 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -409,10 +409,6 @@ chanuserlist Server::GetUsers(chanrec* chan) userl.push_back(i->second); return userl; } -void Server::ChangeUserNick(userrec* user, const std::string &nickname) -{ - force_nickchange(user,nickname.c_str()); -} bool Server::IsUlined(const std::string &server) { diff --git a/src/modules/m_nicklock.cpp b/src/modules/m_nicklock.cpp index 315f8390e..36bf0598d 100644 --- a/src/modules/m_nicklock.cpp +++ b/src/modules/m_nicklock.cpp @@ -55,11 +55,12 @@ class cmd_nicklock : public command_t { // give them a lock flag Srv->SendOpers(std::string(user->nick)+" used NICKLOCK to change and hold "+std::string(parameters[0])+" to "+parameters[1]); - Srv->ChangeUserNick(source,std::string(parameters[1])); - // only attempt to set their lockflag after we know the change succeeded - source = Srv->FindNick(std::string(parameters[1])); - if (source) - source->Extend("nick_locked", "ON"); + if (!source->ForceNickChange(parameters[1])) + { + userrec::QuitUser(source, "Nickname collision"); + return; + } + source->Extend("nick_locked", "ON"); } } } diff --git a/src/modules/m_sanick.cpp b/src/modules/m_sanick.cpp index 09b585b14..561bca613 100644 --- a/src/modules/m_sanick.cpp +++ b/src/modules/m_sanick.cpp @@ -50,7 +50,12 @@ class cmd_sanick : public command_t // FIX by brain: Cant use source->nick here because if it traverses a server link then // source->nick becomes invalid as the object data moves in memory. Srv->SendOpers(std::string(user->nick)+" used SANICK to change "+std::string(parameters[0])+" to "+parameters[1]); - Srv->ChangeUserNick(source,std::string(parameters[1])); + if (!source->ForceNickChange(parameters[1])) + { + /* We couldnt change the nick */ + userrec::QuitUser(source, "Nickname collision"); + return; + } } } } diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index 491c3c471..1e908f07b 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -2014,7 +2014,11 @@ class TreeSocket : public InspSocket /* This is not required as one is sent in OnUserPostNick below */ //DoOneToMany(u->nick,"NICK",par); - Srv->ChangeUserNick(u,params[1]); + if (!u->ForceNickChange(params[1].c_str())) + { + userrec::QuitUser(u, "Nickname collision"); + return true; + } u->age = atoi(params[2].c_str()); } } diff --git a/src/userprocess.cpp b/src/userprocess.cpp index ba05032ca..9c253a074 100644 --- a/src/userprocess.cpp +++ b/src/userprocess.cpp @@ -345,13 +345,13 @@ void DoBackgroundUserStuff(time_t TIME) curr->dns_done = true; //ZapThisDns(curr->fd); ServerInstance->stats->statsDnsBad++; - FullConnectUser(curr,&GlobalGoners); + curr->FullConnect(&GlobalGoners); continue; } if ((curr->dns_done) && (curr->registered == REG_NICKUSER) && (AllModulesReportReady(curr))) { log(DEBUG,"dns done, registered=3, and modules ready, OK"); - FullConnectUser(curr,&GlobalGoners); + curr->FullConnect(&GlobalGoners); //ZapThisDns(curr->fd); continue; } diff --git a/src/users.cpp b/src/users.cpp index 327d0b5bb..61600bd04 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -962,43 +962,42 @@ long FindMatchingLocal(userrec* user) return x; } -void FullConnectUser(userrec* user, CullList* Goners) +void userrec::FullConnect(CullList* Goners) { ServerInstance->stats->statsConnects++; - user->idle_lastmsg = TIME; - log(DEBUG,"ConnectUser: %s",user->nick); + this->idle_lastmsg = TIME; + + ConnectClass a = GetClass(this); - ConnectClass a = GetClass(user); - if (a.type == CC_DENY) { - Goners->AddItem(user,"Unauthorised connection"); + Goners->AddItem(this,"Unauthorised connection"); return; } - if ((*(a.pass.c_str())) && (!user->haspassed)) + if ((*(a.pass.c_str())) && (!this->haspassed)) { - Goners->AddItem(user,"Invalid password"); + Goners->AddItem(this,"Invalid password"); return; } - if (FindMatchingLocal(user) > a.maxlocal) + if (FindMatchingLocal(this) > a.maxlocal) { - Goners->AddItem(user,"No more connections allowed from your host via this connect class (local)"); - WriteOpers("*** WARNING: maximum LOCAL connections (%ld) exceeded for IP %s",a.maxlocal,user->GetIPString()); + Goners->AddItem(this, "No more connections allowed from your host via this connect class (local)"); + WriteOpers("*** WARNING: maximum LOCAL connections (%ld) exceeded for IP %s", a.maxlocal, this->GetIPString()); return; } - else if (FindMatchingGlobal(user) > a.maxglobal) + else if (FindMatchingGlobal(this) > a.maxglobal) { - Goners->AddItem(user,"No more connections allowed from your host via this connect class (global)"); - WriteOpers("*** WARNING: maximum GLOBAL connections (%ld) exceeded for IP %s",a.maxglobal,user->GetIPString()); + Goners->AddItem(this, "No more connections allowed from your host via this connect class (global)"); + WriteOpers("*** WARNING: maximum GLOBAL connections (%ld) exceeded for IP %s",a.maxglobal, this->GetIPString()); return; } char match_against[MAXBUF]; - snprintf(match_against,MAXBUF,"%s@%s",user->ident,user->host); + snprintf(match_against,MAXBUF,"%s@%s", this->ident, this->host); char* e = matches_exception(match_against); - + if (!e) { char* r = matches_gline(match_against); @@ -1007,7 +1006,7 @@ void FullConnectUser(userrec* user, CullList* Goners) { char reason[MAXBUF]; snprintf(reason,MAXBUF,"G-Lined: %s",r); - Goners->AddItem(user,reason); + Goners->AddItem(this, reason); return; } @@ -1017,18 +1016,18 @@ void FullConnectUser(userrec* user, CullList* Goners) { char reason[MAXBUF]; snprintf(reason,MAXBUF,"K-Lined: %s",r); - Goners->AddItem(user,reason); + Goners->AddItem(this, reason); return; } } - WriteServ(user->fd,"NOTICE Auth :Welcome to \002%s\002!",Config->Network); - WriteServ(user->fd,"001 %s :Welcome to the %s IRC Network %s!%s@%s",user->nick,Config->Network,user->nick,user->ident,user->host); - WriteServ(user->fd,"002 %s :Your host is %s, running version %s",user->nick,Config->ServerName,VERSION); - WriteServ(user->fd,"003 %s :This server was created %s %s",user->nick,__TIME__,__DATE__); - WriteServ(user->fd,"004 %s %s %s %s %s %s",user->nick,Config->ServerName,VERSION,ServerInstance->ModeGrok->UserModeList().c_str(),ServerInstance->ModeGrok->ChannelModeList().c_str(),+ServerInstance->ModeGrok->ParaModeList().c_str()); - + WriteServ(this->fd,"NOTICE Auth :Welcome to \002%s\002!",Config->Network); + WriteServ(this->fd,"001 %s :Welcome to the %s IRC Network %s!%s@%s",this->nick, Config->Network, this->nick, this->ident, this->host); + WriteServ(this->fd,"002 %s :Your host is %s, running version %s",this->nick,Config->ServerName,VERSION); + WriteServ(this->fd,"003 %s :This server was created %s %s", this->nick, __TIME__, __DATE__); + WriteServ(this->fd,"004 %s %s %s %s %s %s", this->nick, Config->ServerName, VERSION, ServerInstance->ModeGrok->UserModeList().c_str(), ServerInstance->ModeGrok->ChannelModeList().c_str(), ServerInstance->ModeGrok->ParaModeList().c_str()); + // anfl @ #ratbox, efnet reminded me that according to the RFC this cant contain more than 13 tokens per line... // so i'd better split it :) std::stringstream out(Config->data005); @@ -1044,94 +1043,78 @@ void FullConnectUser(userrec* user, CullList* Goners) if ((token_counter >= 13) || (out.eof() == true)) { - WriteServ(user->fd,"005 %s %s:are supported by this server",user->nick,line5.c_str()); + WriteServ(this->fd,"005 %s %s:are supported by this server", this->nick, line5.c_str()); line5 = ""; token_counter = 0; } } - ShowMOTD(user); + ShowMOTD(this); /* * fix 3 by brain, move registered = 7 below these so that spurious modes and host * changes dont go out onto the network and produce 'fake direction'. */ - FOREACH_MOD(I_OnUserConnect,OnUserConnect(user)); - FOREACH_MOD(I_OnGlobalConnect,OnGlobalConnect(user)); - user->registered = REG_ALL; - WriteOpers("*** Client connecting on port %d: %s!%s@%s [%s]",user->GetPort(),user->nick,user->ident,user->host,user->GetIPString()); + FOREACH_MOD(I_OnUserConnect,OnUserConnect(this)); + FOREACH_MOD(I_OnGlobalConnect,OnGlobalConnect(this)); + this->registered = REG_ALL; + WriteOpers("*** Client connecting on port %d: %s!%s@%s [%s]", this->GetPort(), this->nick, this->ident, this->host, this->GetIPString()); } -/** ReHashNick() +/** userrec::UpdateNick() * re-allocates a nick in the user_hash after they change nicknames, * returns a pointer to the new user as it may have moved */ -userrec* ReHashNick(const char* Old, const char* New) +userrec* userrec::UpdateNickHash(const char* New) { //user_hash::iterator newnick; - user_hash::iterator oldnick = clientlist.find(Old); - - log(DEBUG,"ReHashNick: %s %s",Old,New); + user_hash::iterator oldnick = clientlist.find(this->nick); - if (!strcasecmp(Old,New)) - { - log(DEBUG,"old nick is new nick, skipping"); + if (!strcasecmp(this->nick,New)) return oldnick->second; - } if (oldnick == clientlist.end()) return NULL; /* doesnt exist */ - log(DEBUG,"ReHashNick: Found hashed nick %s",Old); - userrec* olduser = oldnick->second; clientlist[New] = olduser; clientlist.erase(oldnick); - - log(DEBUG,"ReHashNick: Nick rehashed as %s",New); - return clientlist[New]; } -void force_nickchange(userrec* user,const char* newnick) +bool userrec::ForceNickChange(const char* newnick) { char nick[MAXBUF]; int MOD_RESULT = 0; *nick = 0; - FOREACH_RESULT(I_OnUserPreNick,OnUserPreNick(user,newnick)); + FOREACH_RESULT(I_OnUserPreNick,OnUserPreNick(this, newnick)); if (MOD_RESULT) { ServerInstance->stats->statsCollisions++; - userrec::QuitUser(user,"Nickname collision"); - return; + return false; } if (matches_qline(newnick)) { ServerInstance->stats->statsCollisions++; - userrec::QuitUser(user,"Nickname collision"); - return; + return false; } - if (user) + if (newnick) { - if (newnick) - { - strlcpy(nick,newnick,MAXBUF-1); - } - - if (user->registered == REG_ALL) - { - const char* pars[1]; - pars[0] = nick; - std::string cmd = "NICK"; - - ServerInstance->Parser->CallHandler(cmd,pars,1,user); - } + strlcpy(this->nick, newnick, NICKMAX - 1); } + if (this->registered == REG_ALL) + { + const char* pars[1]; + pars[0] = nick; + std::string cmd = "NICK"; + ServerInstance->Parser->CallHandler(cmd, pars, 1, this); + } + return true; } void userrec::SetSockAddr(int protocol_family, const char* ip, int port) |