diff options
author | Adam <Adam@anope.org> | 2012-10-31 12:37:43 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2012-10-31 12:37:43 -0400 |
commit | 3a10fca75f660e90983b3a01d33917c17a0f4fa4 (patch) | |
tree | 6b5a41819a3f1602d381d01d70f773bb39cd4ac2 | |
parent | a39947cd3c6c76cb708de7d328aabde62e39be0b (diff) |
Fix ns_ghost and ns_recover, add nicksev:restoreonghost
-rw-r--r-- | data/nickserv.example.conf | 8 | ||||
-rw-r--r-- | include/config.h | 2 | ||||
-rw-r--r-- | modules/commands/ns_ghost.cpp | 65 | ||||
-rw-r--r-- | modules/commands/ns_recover.cpp | 15 | ||||
-rw-r--r-- | src/config.cpp | 1 |
5 files changed, 65 insertions, 26 deletions
diff --git a/data/nickserv.example.conf b/data/nickserv.example.conf index 20a9f8163..c6a07354f 100644 --- a/data/nickserv.example.conf +++ b/data/nickserv.example.conf @@ -270,6 +270,14 @@ nickserv * This directive is optional. */ #modesonid = "+R" + + /* + * If set, Services will svsnick and svsjoin users who use the ghost + * command to the nick and channels of the ghosted user. + * + * This directive is opional. + */ + restoreonghost = yes } /* diff --git a/include/config.h b/include/config.h index 0f2e127c2..dd00d2666 100644 --- a/include/config.h +++ b/include/config.h @@ -570,6 +570,8 @@ class CoreExport ServerConfig time_t NSKill; /* Modes set on a user when they identify */ Anope::string NSModesOnID; + /* Restore nick/channels on ghost */ + bool NSRestoreOnGhost; /* Core ChanServ modules */ Anope::string ChanCoreModules; diff --git a/modules/commands/ns_ghost.cpp b/modules/commands/ns_ghost.cpp index 53082e0a4..dfc990cab 100644 --- a/modules/commands/ns_ghost.cpp +++ b/modules/commands/ns_ghost.cpp @@ -17,35 +17,64 @@ class NSGhostRequest : public IdentifyRequest { CommandSource source; Command *cmd; + dynamic_reference<User> u; public: - NSGhostRequest(Module *o, CommandSource &src, Command *c, const Anope::string &user, const Anope::string &pass) : IdentifyRequest(o, user, pass), source(src), cmd(c) { } + NSGhostRequest(Module *o, CommandSource &src, Command *c, User *user, const Anope::string &pass) : IdentifyRequest(o, user->nick, pass), source(src), cmd(c), u(user) { } void OnSuccess() anope_override { - if (!source.GetUser() || !source.service) + if (!source.GetUser() || !source.service || !u) return; - User *user = source.GetUser(); - if (!user->IsIdentified()) - source.Reply(_("You may not ghost an unidentified user, use RECOVER instead.")); - else + Anope::string nick = u->nick; + NickCore *acc = u->Account(); + std::vector<std::pair<Anope::string, ChannelStatus> > channels; + for (UChannelList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) + channels.push_back(std::make_pair((*it)->chan->name, *(*it)->Status)); + + Log(LOG_COMMAND, source, cmd) << "for " << GetAccount(); + Anope::string buf = "GHOST command used by " + source.GetNick(); + u->Kill(source.service->nick, buf); + source.Reply(_("Ghost with your nick has been killed.")); + + if (Config->NSRestoreOnGhost) { - Log(LOG_COMMAND, source, cmd) << "for " << GetAccount(); - Anope::string buf = "GHOST command used by " + source.GetNick(); - user->Kill(source.service->nick, buf); - source.Reply(_("Ghost with your nick has been killed.")); + if (acc != NULL) + source.GetUser()->Login(acc); + + ircdproto->SendForceNickChange(source.GetUser(), nick, Anope::CurTime); + + for (unsigned i = 0; i < channels.size(); ++i) + { + ircdproto->SendSVSJoin(source.service, source.GetUser()->GetUID(), channels[i].first, ""); + + Channel *c = findchan(channels[i].first); + if (c) + { + for (size_t j = CMODE_BEGIN + 1; j < CMODE_END; ++j) + if (channels[i].second.HasFlag(static_cast<ChannelModeName>(j))) + c->SetMode(c->ci->WhoSends(), ModeManager::FindChannelModeByName(static_cast<ChannelModeName>(j)), source.GetUser()->GetUID()); + } + } } } void OnFail() anope_override { - source.Reply(ACCESS_DENIED); - if (!GetPassword().empty()) + if (!u) + ; + else if (!findnick(GetAccount())) + source.Reply(NICK_X_NOT_REGISTERED, GetAccount().c_str()); + else { - Log(LOG_COMMAND, source, cmd) << "with an invalid password for " << GetAccount(); - if (source.GetUser()) - bad_password(source.GetUser()); + source.Reply(ACCESS_DENIED); + if (!GetPassword().empty()) + { + Log(LOG_COMMAND, source, cmd) << "with an invalid password for " << GetAccount(); + if (source.GetUser()) + bad_password(source.GetUser()); + } } } }; @@ -72,6 +101,8 @@ class CommandNSGhost : public Command source.Reply(NICK_X_NOT_IN_USE, nick.c_str()); else if (user->server == Me) source.Reply(_("\2%s\2 is a services enforcer."), user->nick.c_str()); + else if (!user->IsIdentified()) + source.Reply(_("You may not ghost an unidentified user, use RECOVER instead.")); else if (!na) source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); else if (na->nc->HasFlag(NI_SUSPENDED)) @@ -90,13 +121,13 @@ class CommandNSGhost : public Command if (ok == false && !pass.empty()) { - NSGhostRequest *req = new NSGhostRequest(owner, source, this, na->nc->display, pass); + NSGhostRequest *req = new NSGhostRequest(owner, source, this, user, pass); FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(source.GetUser(), req)); req->Dispatch(); } else { - NSGhostRequest req(owner, source, this, na->nc->display, pass); + NSGhostRequest req(owner, source, this, user, pass); if (ok) req.OnSuccess(); diff --git a/modules/commands/ns_recover.cpp b/modules/commands/ns_recover.cpp index 648bbf032..63d503553 100644 --- a/modules/commands/ns_recover.cpp +++ b/modules/commands/ns_recover.cpp @@ -19,17 +19,16 @@ class NSRecoverRequest : public IdentifyRequest CommandSource source; Command *cmd; dynamic_reference<NickAlias> na; + dynamic_reference<User> u; public: - NSRecoverRequest(Module *m, CommandSource &src, Command *c, NickAlias *n, const Anope::string &pass) : IdentifyRequest(m, n->nc->display, pass), source(src), cmd(c), na(n) { } + NSRecoverRequest(Module *m, CommandSource &src, Command *c, User *user, NickAlias *n, const Anope::string &pass) : IdentifyRequest(m, n->nc->display, pass), source(src), cmd(c), na(n), u(user) { } void OnSuccess() anope_override { - if (!source.GetUser() || !na) + if (!na || !u) return; - User *u = source.GetUser(); - u->SendMessage(source.service, FORCENICKCHANGE_NOW); if (u->Account() == na->nc) @@ -47,11 +46,9 @@ class NSRecoverRequest : public IdentifyRequest void OnFail() anope_override { - if (!source.GetUser()) + if (!na || !u) return; - User *u = source.GetUser(); - source.Reply(ACCESS_DENIED); if (!GetPassword().empty()) { @@ -101,13 +98,13 @@ class CommandNSRecover : public Command if (ok == false && !pass.empty()) { - NSRecoverRequest *req = new NSRecoverRequest(owner, source, this, na, pass); + NSRecoverRequest *req = new NSRecoverRequest(owner, source, this, u2, na, pass); FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(source.GetUser(), req)); req->Dispatch(); } else { - NSRecoverRequest req(owner, source, this, na, pass); + NSRecoverRequest req(owner, source, this, u2, na, pass); if (ok) req.OnSuccess(); diff --git a/src/config.cpp b/src/config.cpp index 735b4a4e7..002e2917d 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1284,6 +1284,7 @@ ConfigItems::ConfigItems(ServerConfig *conf) {"nickserv", "killquick", "20", new ValueContainerTime(&conf->NSKillQuick), DT_TIME, NoValidation}, {"nickserv", "kill", "60", new ValueContainerTime(&conf->NSKill), DT_TIME, NoValidation}, {"nickserv", "modesonid", "", new ValueContainerString(&conf->NSModesOnID), DT_STRING, NoValidation}, + {"nickserv", "restoreonghost", "yes", new ValueContainerBool(&conf->NSRestoreOnGhost), DT_BOOLEAN, NoValidation}, {"mail", "usemail", "no", new ValueContainerBool(&conf->UseMail), DT_BOOLEAN, ValidateEmailReg}, {"mail", "sendmailpath", "", new ValueContainerString(&conf->SendMailPath), DT_STRING, ValidateMail}, {"mail", "sendfrom", "", new ValueContainerString(&conf->SendFrom), DT_STRING, ValidateMail}, |