diff options
-rw-r--r-- | include/users.h | 3 | ||||
-rw-r--r-- | modules/protocol/bahamut.cpp | 15 | ||||
-rw-r--r-- | modules/protocol/charybdis.cpp | 15 | ||||
-rw-r--r-- | modules/protocol/hybrid.cpp | 19 | ||||
-rw-r--r-- | modules/protocol/inspircd12.cpp | 137 | ||||
-rw-r--r-- | modules/protocol/inspircd20.cpp | 68 | ||||
-rw-r--r-- | modules/protocol/ngircd.cpp | 2 | ||||
-rw-r--r-- | modules/protocol/plexus.cpp | 14 | ||||
-rw-r--r-- | modules/protocol/ratbox.cpp | 8 | ||||
-rw-r--r-- | modules/protocol/unreal.cpp | 9 | ||||
-rw-r--r-- | modules/pseudoclients/hostserv.cpp | 9 | ||||
-rw-r--r-- | modules/pseudoclients/nickserv.cpp | 4 | ||||
-rw-r--r-- | src/bots.cpp | 2 | ||||
-rw-r--r-- | src/users.cpp | 7 |
14 files changed, 181 insertions, 131 deletions
diff --git a/include/users.h b/include/users.h index 768b6dfa1..e76c2a427 100644 --- a/include/users.h +++ b/include/users.h @@ -102,8 +102,9 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe * @param ssignon User's timestamp * @param smodes User's modes * @param suid The unique identifier of the user. + * @param nc The account the user is identified as, if any */ - User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ssignon, const Anope::string &smodes, const Anope::string &suid = ""); + User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ssignon, const Anope::string &smodes, const Anope::string &suid, NickCore *nc); protected: /** Destroy a user. diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index d65c24d65..4b6feae2d 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -379,14 +379,13 @@ struct IRCDMessageNick : IRCDMessage return; } - User *user = new User(params[0], params[4], params[5], "", params[8], s, params[9], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3]); - try - { - NickAlias *na; - if (user->signon == convertTo<time_t>(params[7]) && (na = NickAlias::Find(user->nick))) - user->Login(na->nc); - } - catch (const ConvertException &) { } + NickAlias *na = NULL; + time_t signon = params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, + stamp = params[7].is_pos_number_only() ? convertTo<time_t>(params[7]) : 0; + if (signon && signon == stamp) + na = NickAlias::Find(params[0]); + + new User(params[0], params[4], params[5], "", params[8], s, params[9], signon, params[3], "", na ? *na->nc : NULL); } else source.GetUser()->ChangeNick(params[0]); diff --git a/modules/protocol/charybdis.cpp b/modules/protocol/charybdis.cpp index 9b87f3230..cc9f8a58b 100644 --- a/modules/protocol/charybdis.cpp +++ b/modules/protocol/charybdis.cpp @@ -283,20 +283,11 @@ struct IRCDMessageEUID : IRCDMessage */ void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { - /* Source is always the server */ - User *u = new User(params[0], params[4], params[8], params[5], params[6], source.GetServer(), params[10], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime, params[3], params[7]); + NickAlias *na = NULL; if (params[9] != "*") - { - NickAlias *na = NickAlias::Find(params[9]); - if (na) - { - u->Login(na->nc); + na = NickAlias::Find(params[9]); - BotInfo *NickServ = Config->GetClient("NickServ"); - if (u->server->IsSynced() && NickServ) - u->SendMessage(NickServ, _("You have been logged in as \2%s\2."), na->nc->display.c_str()); - } - } + new User(params[0], params[4], params[8], params[5], params[6], source.GetServer(), params[10], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime, params[3], params[7], na ? *na->nc : NULL); } }; diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index f10f0a26b..84cd73800 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -497,18 +497,15 @@ struct IRCDMessageUID : IRCDMessage if (ip == "0") /* Can be 0 for spoofed clients */ ip.clear(); - /* Source is always the server */ - User *user = new User(params[0], params[4], params[5], "", - ip, source.GetServer(), - params[9], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, - params[3], params[7]); - + NickAlias *na = NULL; if (params[8] != "0") - { - NickAlias *na = NickAlias::Find(params[8]); - if (na != NULL) - user->Login(na->nc); - } + na = NickAlias::Find(params[8]); + + /* Source is always the server */ + new User(params[0], params[4], params[5], "", + ip, source.GetServer(), + params[9], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, + params[3], params[7], na ? *na->nc : NULL); } }; diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp index c257f5d1e..3a2eb2d8a 100644 --- a/modules/protocol/inspircd12.cpp +++ b/modules/protocol/inspircd12.cpp @@ -11,6 +11,16 @@ #include "module.h" +struct SASLUser +{ + Anope::string uid; + Anope::string acc; + time_t created; +}; + +static bool sasl = true; +static std::list<SASLUser> saslusers; + class ChannelModeFlood : public ChannelModeParam { public: @@ -924,17 +934,7 @@ struct IRCDMessageMetadata : IRCDMessage User *u = User::Find(params[0]); NickCore *nc = NickCore::Find(params[2]); if (u && nc) - { u->Login(nc); - - BotInfo *NickServ = Config->GetClient("nickserv"); - - /* Sometimes a user connects, we send them the usual "this nickname is registered" mess (if - * their server isn't syncing) and then we receive this.. so tell them about it. - */ - if (u->server->IsSynced() && NickServ) - u->SendMessage(NickServ, _("You have been logged in as \002%s\002."), nc->display.c_str()); - } } /* @@ -1157,7 +1157,114 @@ struct IRCDMessageUID : IRCDMessage for (unsigned i = 9; i < params.size() - 1; ++i) modes += " " + params[i]; - new User(params[2], params[5], params[3], params[4], params[6], source.GetServer(), params[params.size() - 1], ts, modes, params[0]); + NickAlias *na = NULL; + if (sasl) + for (std::list<SASLUser>::iterator it = saslusers.begin(); it != saslusers.end();) + { + SASLUser &u = *it; + + if (u.created + 30 < Anope::CurTime) + it = saslusers.erase(it); + else if (u.uid == params[0]) + { + na = NickAlias::Find(u.acc); + it = saslusers.erase(it); + } + else + ++it; + } + + new User(params[2], params[5], params[3], params[4], params[6], source.GetServer(), params[params.size() - 1], ts, modes, params[0], na ? *na->nc : NULL); + } +}; + +struct IRCDMessageEncap : IRCDMessage +{ + IRCDMessageEncap(Module *creator) : IRCDMessage(creator, "ENCAP", 4) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + if (Anope::Match(Me->GetSID(), params[0]) == false) + return; + + if (sasl && params[1] == "SASL" && params.size() == 6) + { + class InspIRCDSASLIdentifyRequest : public IdentifyRequest + { + Anope::string uid; + + public: + InspIRCDSASLIdentifyRequest(Module *m, const Anope::string &id, const Anope::string &acc, const Anope::string &pass) : IdentifyRequest(m, acc, pass), uid(id) { } + + void OnSuccess() anope_override + { + UplinkSocket::Message(Me) << "METADATA " << this->uid << " accountname :" << this->GetAccount(); + UplinkSocket::Message(Me) << "ENCAP " << this->uid.substr(0, 3) << " SASL " << Me->GetSID() << " " << this->uid << " D S"; + + SASLUser su; + su.uid = this->uid; + su.acc = this->GetAccount(); + su.created = Anope::CurTime; + + for (std::list<SASLUser>::iterator it = saslusers.begin(); it != saslusers.end();) + { + SASLUser &u = *it; + + if (u.created + 30 < Anope::CurTime || u.uid == this->uid) + it = saslusers.erase(it); + else + ++it; + } + + saslusers.push_back(su); + } + + void OnFail() anope_override + { + UplinkSocket::Message(Me) << "ENCAP " << this->uid.substr(0, 3) << " SASL " << Me->GetSID() << " " << this->uid << " " << " D F"; + + Log(Config->GetClient("NickServ")) << "A user failed to identify for account " << this->GetAccount() << " using SASL"; + } + }; + + /* + Received: :869 ENCAP * SASL 869AAAAAH * S PLAIN + Sent: :00B ENCAP 869 SASL 00B 869AAAAAH C + + Received: :869 ENCAP * SASL 869AAAAAH 00B C QWRhbQBBZGFtAG1vbw== + base64(account\0account\0pass) + */ + if (params[4] == "S") + { + if (params[5] == "PLAIN") + UplinkSocket::Message(Me) << "ENCAP " << params[2].substr(0, 3) << " SASL " << Me->GetSID() << " " << params[2] << " C +"; + else + UplinkSocket::Message(Me) << "ENCAP " << params[2].substr(0, 3) << " SASL " << Me->GetSID() << " " << params[2] << " D F"; + } + else if (params[4] == "C") + { + Anope::string decoded; + Anope::B64Decode(params[5], decoded); + + size_t p = decoded.find('\0'); + if (p == Anope::string::npos) + return; + decoded = decoded.substr(p + 1); + + p = decoded.find('\0'); + if (p == Anope::string::npos) + return; + + Anope::string acc = decoded.substr(0, p), + pass = decoded.substr(p + 1); + + if (acc.empty() || pass.empty()) + return; + + IdentifyRequest *req = new InspIRCDSASLIdentifyRequest(this->owner, params[2], acc, pass); + FOREACH_MOD(OnCheckAuthentication, (NULL, req)); + req->Dispatch(); + } + } } }; @@ -1200,6 +1307,7 @@ class ProtoInspIRCd : public Module IRCDMessageServer message_server; IRCDMessageTime message_time; IRCDMessageUID message_uid; + IRCDMessageEncap message_encap; public: ProtoInspIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), @@ -1211,7 +1319,7 @@ class ProtoInspIRCd : public Module message_chgident(this), message_setname(this, "SETNAME"), message_chgname(this, "FNAME"), message_capab(this), message_endburst(this), message_fhost(this, "FHOST"), message_sethost(this, "SETHOST"), message_fjoin(this), message_fmode(this), message_ftopic(this), message_idle(this), message_metadata(this), message_mode(this), message_nick(this), message_opertype(this), message_rsquit(this), - message_setident(this), message_server(this), message_time(this), message_uid(this) + message_setident(this), message_server(this), message_time(this), message_uid(this), message_encap(this) { @@ -1224,6 +1332,11 @@ class ProtoInspIRCd : public Module it->second->GenerateUID(); } + void OnReload(Configuration::Conf *conf) anope_override + { + sasl = conf->GetModule(this)->Get<bool>("sasl") || conf->GetModule("inspircd20")->Get<bool>("sasl"); + } + void OnUserNickChange(User *u, const Anope::string &) anope_override { /* InspIRCd 1.2 doesn't set -r on nick change, remove -r here. Note that if we have to set +r later diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index 673836d93..73f573e5b 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -11,7 +11,6 @@ #include "module.h" -static bool sasl = true; static unsigned int spanningtree_proto_ver = 0; static ServiceReference<IRCDProto> insp12("IRCDProto", "inspircd12"); @@ -608,7 +607,9 @@ struct IRCDMessageCapab : Message::Capab struct IRCDMessageEncap : IRCDMessage { - IRCDMessageEncap(Module *creator) : IRCDMessage(creator, "ENCAP", 4) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + ServiceReference<IRCDMessage> insp12_encap; + + IRCDMessageEncap(Module *creator) : IRCDMessage(creator, "ENCAP", 4), insp12_encap("IRCDMessage", "inspircd12/encap") { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { @@ -642,67 +643,9 @@ struct IRCDMessageEncap : IRCDMessage u->SetRealname(params[3]); UplinkSocket::Message(u) << "FNAME " << params[3]; } - else if (sasl && params[1] == "SASL" && params.size() == 6) - { - class InspIRCDSASLIdentifyRequest : public IdentifyRequest - { - Anope::string uid; - public: - InspIRCDSASLIdentifyRequest(Module *m, const Anope::string &id, const Anope::string &acc, const Anope::string &pass) : IdentifyRequest(m, acc, pass), uid(id) { } - - void OnSuccess() anope_override - { - UplinkSocket::Message(Me) << "METADATA " << this->uid << " accountname :" << this->GetAccount(); - UplinkSocket::Message(Me) << "ENCAP " << this->uid.substr(0, 3) << " SASL " << Me->GetSID() << " " << this->uid << " D S"; - } - - void OnFail() anope_override - { - UplinkSocket::Message(Me) << "ENCAP " << this->uid.substr(0, 3) << " SASL " << Me->GetSID() << " " << this->uid << " " << " D F"; - - Log(Config->GetClient("NickServ")) << "A user failed to identify for account " << this->GetAccount() << " using SASL"; - } - }; - - /* - Received: :869 ENCAP * SASL 869AAAAAH * S PLAIN - Sent: :00B ENCAP 869 SASL 00B 869AAAAAH C + - Received: :869 ENCAP * SASL 869AAAAAH 00B C QWRhbQBBZGFtAG1vbw== - base64(account\0account\0pass) - */ - if (params[4] == "S") - { - if (params[5] == "PLAIN") - UplinkSocket::Message(Me) << "ENCAP " << params[2].substr(0, 3) << " SASL " << Me->GetSID() << " " << params[2] << " C +"; - else - UplinkSocket::Message(Me) << "ENCAP " << params[2].substr(0, 3) << " SASL " << Me->GetSID() << " " << params[2] << " D F"; - } - else if (params[4] == "C") - { - Anope::string decoded; - Anope::B64Decode(params[5], decoded); - - size_t p = decoded.find('\0'); - if (p == Anope::string::npos) - return; - decoded = decoded.substr(p + 1); - - p = decoded.find('\0'); - if (p == Anope::string::npos) - return; - - Anope::string acc = decoded.substr(0, p), - pass = decoded.substr(p + 1); - - if (acc.empty() || pass.empty()) - return; - - IdentifyRequest *req = new InspIRCDSASLIdentifyRequest(this->owner, params[2], acc, pass); - FOREACH_MOD(OnCheckAuthentication, (NULL, req)); - req->Dispatch(); - } - } + if (insp12_encap) + insp12_encap->Run(source, params); } }; @@ -801,7 +744,6 @@ class ProtoInspIRCd : public Module { use_server_side_topiclock = conf->GetModule(this)->Get<bool>("use_server_side_topiclock"); use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock"); - sasl = conf->GetModule(this)->Get<bool>("sasl"); } void OnUserNickChange(User *u, const Anope::string &) anope_override diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp index a8ddeed30..a22828e3d 100644 --- a/modules/protocol/ngircd.cpp +++ b/modules/protocol/ngircd.cpp @@ -420,7 +420,7 @@ struct IRCDMessageNick : IRCDMessage else if (params.size() == 7) { // a new user is connecting to the network - new User(params[0], params[2], params[3], "", "", source.GetServer(), params[6], Anope::CurTime, params[5], ""); + new User(params[0], params[2], params[3], "", "", source.GetServer(), params[6], Anope::CurTime, params[5], "", NULL); } else { diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp index e3efdc6e6..cacaa59d0 100644 --- a/modules/protocol/plexus.cpp +++ b/modules/protocol/plexus.cpp @@ -270,17 +270,17 @@ struct IRCDMessageUID : IRCDMessage ts = Anope::CurTime; } - User *user = new User(params[0], params[4], params[9], params[5], ip, source.GetServer(), params[10], ts, params[3], params[7]); + NickAlias *na = NULL; try { - if (params[8].is_pos_number_only() && convertTo<time_t>(params[8]) == user->timestamp) - { - NickAlias *na = NickAlias::Find(user->nick); - if (na) - user->Login(na->nc); - } + if (params[8].is_pos_number_only() && convertTo<time_t>(params[8]) == ts) + na = NickAlias::Find(params[0]); } catch (const ConvertException &) { } + if (params[8] != "0" && !na) + na = NickAlias::Find(params[8]); + + new User(params[0], params[4], params[9], params[5], ip, source.GetServer(), params[10], ts, params[3], params[7], na ? *na->nc : NULL); } }; diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp index 2d077e37b..7bae048d6 100644 --- a/modules/protocol/ratbox.cpp +++ b/modules/protocol/ratbox.cpp @@ -105,6 +105,12 @@ struct IRCDMessageEncap : IRCDMessage if (!nc) return; u->Login(nc); + + /* Sometimes a user connects, we send them the usual "this nickname is registered" mess (if + * their server isn't syncing) and then we receive this.. so tell them about it. + */ + if (u->server->IsSynced()) + u->SendMessage(Config->GetClient("NickServ"), _("You have been logged in as \002%s\002."), nc->display.c_str()); } } }; @@ -167,7 +173,7 @@ struct IRCDMessageUID : IRCDMessage void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { /* Source is always the server */ - new User(params[0], params[4], params[5], "", params[6], source.GetServer(), params[8], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3], params[7]); + new User(params[0], params[4], params[5], "", params[6], source.GetServer(), params[8], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3], params[7], NULL); } }; diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp index fa6dc15ed..5e6534409 100644 --- a/modules/protocol/unreal.cpp +++ b/modules/protocol/unreal.cpp @@ -803,24 +803,21 @@ struct IRCDMessageNick : IRCDMessage return; } - User *user = new User(params[0], params[3], params[4], vhost, ip, s, params[10], user_ts, params[7]); - NickAlias *na = NULL; if (params[6] == "0") ; else if (params[6].is_pos_number_only()) { - if (convertTo<time_t>(params[6]) == user->signon) - na = NickAlias::Find(user->nick); + if (convertTo<time_t>(params[6]) == user_ts) + na = NickAlias::Find(params[0]); } else { na = NickAlias::Find(params[6]); } - if (na) - user->Login(na->nc); + new User(params[0], params[3], params[4], vhost, ip, s, params[10], user_ts, params[7], "", na ? *na->nc : NULL); } else source.GetUser()->ChangeNick(params[0]); diff --git a/modules/pseudoclients/hostserv.cpp b/modules/pseudoclients/hostserv.cpp index 31b623895..2ac0d8f09 100644 --- a/modules/pseudoclients/hostserv.cpp +++ b/modules/pseudoclients/hostserv.cpp @@ -35,12 +35,15 @@ class HostServCore : public Module HostServ = bi; } - void OnNickIdentify(User *u) anope_override + void OnUserLogin(User *u) anope_override { + if (!IRCD->CanSetVHost) + return; + const NickAlias *na = NickAlias::Find(u->nick); - if (!na || !na->HasVhost()) + if (!na || na->nc != u->Account() || !na->HasVhost()) na = NickAlias::Find(u->Account()->display); - if (!IRCD->CanSetVHost || !na || !na->HasVhost()) + if (!na || !na->HasVhost()) return; if (u->vhost.empty() || !u->vhost.equals_cs(na->GetVhostHost()) || (!na->GetVhostIdent().empty() && !u->GetVIdent().equals_cs(na->GetVhostIdent()))) diff --git a/modules/pseudoclients/nickserv.cpp b/modules/pseudoclients/nickserv.cpp index 9d05c339f..f306b1b51 100644 --- a/modules/pseudoclients/nickserv.cpp +++ b/modules/pseudoclients/nickserv.cpp @@ -64,7 +64,7 @@ class NickServRelease : public User, public Timer public: NickServRelease(NickAlias *na, time_t delay) : User(na->nick, Config->GetBlock("options")->Get<const Anope::string>("enforceruser"), - Config->GetBlock("options")->Get<const Anope::string>("enforcerhost"), "", "", Me, "Services Enforcer", Anope::CurTime, "", Servers::TS6_UID_Retrieve()), Timer(delay), nick(na->nick) + Config->GetBlock("options")->Get<const Anope::string>("enforcerhost"), "", "", Me, "Services Enforcer", Anope::CurTime, "", Servers::TS6_UID_Retrieve(), NULL), Timer(delay), nick(na->nick) { /* Erase the current release timer and use the new one */ std::map<Anope::string, NickServRelease *>::iterator nit = NickServReleases.find(this->nick); @@ -368,7 +368,7 @@ class NickServCore : public Module, public NickServService const Anope::string &unregistered_notice = Config->GetModule(this)->Get<const Anope::string>("unregistered_notice"); if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && !unregistered_notice.empty() && !na) u->SendMessage(NickServ, unregistered_notice); - else if (na) + else if (na && !u->IsIdentified(true)) this->Validate(u); } diff --git a/src/bots.cpp b/src/bots.cpp index e2c346837..243d2ab89 100644 --- a/src/bots.cpp +++ b/src/bots.cpp @@ -21,7 +21,7 @@ Serialize::Checker<botinfo_map> BotListByNick("BotInfo"), BotListByUID("BotInfo"); -BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : User(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", Servers::TS6_UID_Retrieve()), Serializable("BotInfo"), channels("ChannelInfo"), botmodes(bmodes) +BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : User(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", Servers::TS6_UID_Retrieve(), NULL), Serializable("BotInfo"), channels("ChannelInfo"), botmodes(bmodes) { this->lastmsg = this->created = Anope::CurTime; this->introduced = false; diff --git a/src/users.cpp b/src/users.cpp index cc99cd63e..cd3c6b50f 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -32,7 +32,7 @@ time_t MaxUserTime = 0; std::list<User *> User::quitting_users; -User::User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ssignon, const Anope::string &smodes, const Anope::string &suid) +User::User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ssignon, const Anope::string &smodes, const Anope::string &suid, NickCore *account) { if (snick.empty() || sident.empty() || shost.empty()) throw CoreException("Bad args passed to User::User"); @@ -55,6 +55,7 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope: this->SetModesInternal("%s", smodes.c_str()); this->uid = suid; this->super_admin = false; + this->nc = NULL; size_t old = UserListByNick.size(); UserListByNick[snick] = this; @@ -63,7 +64,7 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope: if (old == UserListByNick.size()) Log(LOG_DEBUG) << "Duplicate user " << snick << " in user table?"; - this->nc = NULL; + this->Login(account); this->UpdateHost(); if (sserver && sserver->IsSynced()) // Our bots are introduced on startup with no server @@ -326,7 +327,7 @@ void User::Identify(NickAlias *na) void User::Login(NickCore *core) { - if (core == this->nc) + if (!core || core == this->nc) return; this->Logout(); |