X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fusers.cpp;h=eb87824fcf1f22d7ba543f49edc6d61931c1d9f7;hb=0a1f9bc59494a532a91bc9c8afcecb31ece656ee;hp=e17c8cd79417764df5bc883231aa2b811c64e229;hpb=b2ac8cc0a6405946a388b80df3be21bc276a61f3;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/users.cpp b/src/users.cpp index e17c8cd79..eb87824fc 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -318,10 +318,11 @@ void UserIOHandler::AddWriteBuf(const std::string &data) WriteData(data); } -void UserIOHandler::OnSetEndPoint(const irc::sockets::sockaddrs& server, const irc::sockets::sockaddrs& client) +bool UserIOHandler::OnSetEndPoint(const irc::sockets::sockaddrs& server, const irc::sockets::sockaddrs& client) { memcpy(&user->server_sa, &server, sizeof(irc::sockets::sockaddrs)); user->SetClientIP(client); + return !user->quitting; } void UserIOHandler::OnError(BufferedSocketError) @@ -357,10 +358,12 @@ CullResult FakeUser::cull() void User::Oper(OperInfo* info) { ModeHandler* opermh = ServerInstance->Modes->FindMode('o', MODETYPE_USER); - if (this->IsModeSet(opermh)) - this->UnOper(); - - this->SetMode(opermh, true); + if (opermh) + { + if (this->IsModeSet(opermh)) + this->UnOper(); + this->SetMode(opermh, true); + } this->oper = info; LocalUser* localuser = IS_LOCAL(this); @@ -474,7 +477,8 @@ void User::UnOper() stdalgo::vector::swaperase(ServerInstance->Users->all_opers, this); ModeHandler* opermh = ServerInstance->Modes->FindMode('o', MODETYPE_USER); - this->SetMode(opermh, false); + if (opermh) + this->SetMode(opermh, false); FOREACH_MOD(OnPostDeoper, (this)); } @@ -557,45 +561,15 @@ void LocalUser::FullConnect() if (quitting) return; - this->WriteNumeric(RPL_WELCOME, InspIRCd::Format("Welcome to the %s IRC Network %s", ServerInstance->Config->Network.c_str(), GetFullRealHost().c_str())); - this->WriteNumeric(RPL_YOURHOSTIS, InspIRCd::Format("Your host is %s, running version %s", ServerInstance->Config->ServerName.c_str(), INSPIRCD_BRANCH)); - this->WriteNumeric(RPL_SERVERCREATED, InspIRCd::TimeString(ServerInstance->startup_time, "This server was created %H:%M:%S %b %d %Y")); - - const TR1NS::array& modelist = ServerInstance->Modes->GetModeListFor004Numeric(); - this->WriteNumeric(RPL_SERVERVERSION, ServerInstance->Config->ServerName, INSPIRCD_BRANCH, modelist[0], modelist[1], modelist[2]); - - ServerInstance->ISupport.SendTo(this); - - /* Now registered */ - if (ServerInstance->Users->unregistered_count) - ServerInstance->Users->unregistered_count--; - - /* Trigger MOTD and LUSERS output, give modules a chance too */ - ModResult MOD_RESULT; - std::string command("LUSERS"); - CommandBase::Params parameters; - FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, parameters, this, true)); - if (!MOD_RESULT) - ServerInstance->Parser.CallHandler(command, parameters, this); - - MOD_RESULT = MOD_RES_PASSTHRU; - command = "MOTD"; - FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, parameters, this, true)); - if (!MOD_RESULT) - ServerInstance->Parser.CallHandler(command, parameters, this); - - if (ServerInstance->Config->RawLog) - { - ClientProtocol::Messages::Privmsg rawlogmsg(ServerInstance->FakeClient, this, "*** Raw I/O logging is enabled on this server. All messages, passwords, and commands are being recorded."); - this->Send(ServerInstance->GetRFCEvents().privmsg, rawlogmsg); - } - /* * 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. */ FOREACH_MOD(OnUserConnect, (this)); + /* Now registered */ + if (ServerInstance->Users->unregistered_count) + ServerInstance->Users->unregistered_count--; this->registered = REG_ALL; FOREACH_MOD(OnPostConnect, (this)); @@ -750,39 +724,56 @@ irc::sockets::cidr_mask User::GetCIDRMask() return irc::sockets::cidr_mask(client_sa, range); } -bool User::SetClientIP(const std::string& address, bool recheck_eline) +bool User::SetClientIP(const std::string& address) { - this->InvalidateCache(); - return irc::sockets::aptosa(address, 0, client_sa); + irc::sockets::sockaddrs sa; + if (!irc::sockets::aptosa(address, client_sa.port(), sa)) + return false; + + User::SetClientIP(sa); + return true; } -void User::SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline) +void User::SetClientIP(const irc::sockets::sockaddrs& sa) { - this->InvalidateCache(); + const std::string oldip(GetIPString()); memcpy(&client_sa, &sa, sizeof(irc::sockets::sockaddrs)); + this->InvalidateCache(); + + // If the users hostname was their IP then update it. + if (GetRealHost() == oldip) + ChangeRealHost(GetIPString(), false); + if (GetDisplayedHost() == oldip) + ChangeDisplayedHost(GetIPString()); } -bool LocalUser::SetClientIP(const std::string& address, bool recheck_eline) +bool LocalUser::SetClientIP(const std::string& address) { irc::sockets::sockaddrs sa; - if (!irc::sockets::aptosa(address, 0, sa)) - // Invalid + if (!irc::sockets::aptosa(address, client_sa.port(), sa)) return false; - LocalUser::SetClientIP(sa, recheck_eline); + LocalUser::SetClientIP(sa); return true; } -void LocalUser::SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline) +void LocalUser::SetClientIP(const irc::sockets::sockaddrs& sa) { - if (sa != client_sa) - { - User::SetClientIP(sa); - if (recheck_eline) - this->exempt = (ServerInstance->XLines->MatchesLine("E", this) != NULL); + if (sa == client_sa) + return; - FOREACH_MOD(OnSetUserIP, (this)); - } + ServerInstance->Users->RemoveCloneCounts(this); + + User::SetClientIP(sa); + + FOREACH_MOD(OnSetUserIP, (this)); + + ServerInstance->Users->AddClone(this); + + // Recheck the connect class. + this->MyClass = NULL; + this->SetClass(); + this->CheckClass(); } void LocalUser::Write(const ClientProtocol::SerializedMessage& text) @@ -813,7 +804,11 @@ void LocalUser::Write(const ClientProtocol::SerializedMessage& text) void LocalUser::Send(ClientProtocol::Event& protoev) { if (!serializer) + { + ServerInstance->Logs->Log("USERS", LOG_DEBUG, "BUG: LocalUser::Send() called on %s who does not have a serializer!", + GetFullRealHost().c_str()); return; + } // In the most common case a static LocalUser field, sendmsglist, is passed to the event to be // populated. The list is cleared before returning. @@ -1181,8 +1176,6 @@ void User::PurgeEmptyChannels() ++i; c->DelUser(this); } - - this->UnOper(); } void User::WriteNotice(const std::string& text)