void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { const Anope::string &nick = params[0]; if (Anope::ReadOnly) source.Reply(_("Services are in read-only mode. Any changes made may not persist.")); NickServ::Nick *na = NickServ::FindNick(nick); if (!na) { source.Reply(_("\002{0}\002 isn't registered."), nick); return; } NSSuspendInfo *si = na->GetAccount()->GetRef<NSSuspendInfo *>(); if (!si) { source.Reply(_("\002{0}\002 is not suspended."), na->GetNick()); return; } Log(LOG_ADMIN, source, this) << "for " << na->GetNick() << " which was suspended by " << (!si->GetBy().empty() ? si->GetBy() : "(none)") << " for: " << (!si->GetReason().empty() ? si->GetReason() : "No reason"); si->Delete(); source.Reply(_("\002{0}\002 is now released."), na->GetNick()); EventManager::Get()->Dispatch(&Event::NickUnsuspend::OnNickUnsuspend, na); }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { if (Anope::ReadOnly) { source.Reply(_("Services are in read-only mode.")); return; } const Anope::string &nick = params[0]; NickServ::Nick *na = NickServ::FindNick(nick); if (!na) { source.Reply(_("\002{0}\002 isn't registered."), nick); return; } HostRequest *req = na->GetExt<HostRequest>("hostrequest"); if (!req) { source.Reply(_("\002{0}\002 does not have a pending vhost request."), na->GetNick()); return; } na->SetVhost(req->GetIdent(), req->GetHost(), source.GetNick(), req->GetTime()); EventManager::Get()->Dispatch(&Event::SetVhost::OnSetVhost, na); if (Config->GetModule(this->GetOwner())->Get<bool>("memouser") && memoserv) memoserv->Send(source.service->nick, na->GetNick(), _("[auto memo] Your requested vHost has been approved."), true); source.Reply(_("Vhost for \002{0}\002 has been activated."), na->GetNick()); Log(LOG_COMMAND, source, this) << "for " << na->GetNick() << " for vhost " << (!req->GetIdent().empty() ? req->GetIdent() + "@" : "") << req->GetHost(); req->Delete(); }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { const Anope::string &nick = params[0]; const Anope::string &pass = params.size() > 1 ? params[1] : ""; User *user = User::Find(nick, true); if (user && source.GetUser() == user) { source.Reply(_("You can't %s yourself!"), source.command.lower().c_str()); return; } NickServ::Nick *na = NickServ::FindNick(nick); if (!na) { source.Reply(_("\002{0}\002 isn't registered."), nick); return; } if (na->GetAccount()->HasFieldS("NS_SUSPENDED")) { source.Reply(_("\002{0}\002 is suspended."), na->GetNick()); return; } bool ok = false; if (source.GetAccount() == na->GetAccount()) ok = true; else if (!na->GetAccount()->HasFieldS("NS_SECURE") && source.GetUser() && na->GetAccount()->IsOnAccess(source.GetUser())) ok = true; if (certservice && source.GetUser() && certservice->Matches(source.GetUser(), na->GetAccount())) ok = true; if (ok == false && !pass.empty()) { NickServ::IdentifyRequest *req = NickServ::service->CreateIdentifyRequest(new NSRecoverRequestListener(source, this, na->GetNick(), pass), owner, na->GetNick(), pass); Event::OnCheckAuthentication(&Event::CheckAuthentication::OnCheckAuthentication, source.GetUser(), req); req->Dispatch(); } else { NSRecoverRequestListener req(source, this, na->GetNick(), pass); if (ok) req.OnSuccess(nullptr); else req.OnFail(nullptr); } }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { User *u = source.GetUser(); Anope::string nick = !params.empty() ? params[0] : ""; NickServ::Nick *na = NickServ::FindNick(!nick.empty() ? nick : u->nick); if (u->Account()->GetRefs<NickServ::Nick *>().size() == 1) { source.Reply(_("Your nickname is not grouped to anything, so you can't ungroup it.")); return; } if (!na) { source.Reply(_("\002{0}\002 isn't registered."), !nick.empty() ? nick : u->nick); return; } if (na->GetAccount() != u->Account()) { source.Reply(_("\002{0}\002 is not in your group."), na->GetNick()); return; } NickServ::Account *oldcore = na->GetAccount(); if (na->GetNick().equals_ci(oldcore->GetDisplay())) oldcore->SetDisplay(oldcore->GetRef<NickServ::Nick *>()); NickServ::Account *nc = Serialize::New<NickServ::Account *>(); nc->SetDisplay(na->GetNick()); na->SetAccount(nc); nc->SetPassword(oldcore->GetPassword()); if (!oldcore->GetEmail().empty()) nc->SetEmail(oldcore->GetEmail()); nc->SetLanguage(oldcore->GetLanguage()); source.Reply(_("\002{0}\002 has been ungrouped from \002{1}\002."), na->GetNick(), oldcore->GetDisplay()); User *user = User::Find(na->GetNick()); if (user) /* The user on the nick who was ungrouped may be identified to the old group, set -r */ user->RemoveMode(source.service, "REGISTERED"); }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { if (Anope::ReadOnly) { source.Reply(_("Services are in read-only mode.")); return; } const Anope::string &nick = params[0]; const Anope::string &reason = params.size() > 1 ? params[1] : ""; NickServ::Nick *na = NickServ::FindNick(nick); if (!na) { source.Reply(_("\002{0}\002 isn't registered."), nick); return; } HostRequest *req = na->GetExt<HostRequest>("hostrequest"); if (!req) { source.Reply(_("\002{0}\002 does not have a pending vhost request."), na->GetNick()); return; } req->Delete(); if (Config->GetModule(this->GetOwner())->Get<bool>("memouser") && memoserv) { Anope::string message; if (!reason.empty()) message = Anope::printf(_("[auto memo] Your requested vHost has been rejected. Reason: %s"), reason.c_str()); else message = _("[auto memo] Your requested vHost has been rejected."); memoserv->Send(source.service->nick, nick, Language::Translate(source.GetAccount(), message.c_str()), true); } source.Reply(_("Vhost for \002{0}\002 has been rejected."), na->GetNick()); Log(LOG_COMMAND, source, this) << "to reject vhost for " << nick << " (" << (!reason.empty() ? reason : "no reason") << ")"; }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { NickServ::Nick *na = NickServ::FindNick(params[0]); if (!na) { source.Reply(_("\002{0}\002 isn't registered."), params[0]); return; } if (!na->GetAccount()->GetEmail().equals_ci(params[1])) { source.Reply(_("Incorrect email address.")); return; } if (SendResetEmail(source.GetUser(), na, source.service)) { Log(LOG_COMMAND, source, this) << "for " << na->GetNick() << " (group: " << na->GetAccount()->GetDisplay() << ")"; source.Reply(_("Password reset email for \002{0}\002 has been sent."), na->GetNick()); } }
void SendMemos(CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost) { Anope::string host; if (!vIdent.empty()) host = vIdent + "@" + vHost; else host = vHost; if (Config->GetModule(GetOwner())->Get<bool>("memooper") && memoserv) for (Oper *o : Serialize::GetObjects<Oper *>()) { NickServ::Nick *na = NickServ::FindNick(o->GetName()); if (!na) continue; Anope::string message = Anope::printf(_("[auto memo] vHost \002%s\002 has been requested by %s."), host.c_str(), source.GetNick().c_str()); memoserv->Send(source.service->nick, na->GetNick(), message, true); } }
static void req_send_memos(Module *me, CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost) { Anope::string host; std::list<std::pair<Anope::string, Anope::string> >::iterator it, it_end; if (!vIdent.empty()) host = vIdent + "@" + vHost; else host = vHost; if (Config->GetModule(me)->Get<bool>("memooper") && MemoServ::service) for (Oper *o : Serialize::GetObjects<Oper *>(operblock)) { NickServ::Nick *na = NickServ::FindNick(o->GetName()); if (!na) continue; Anope::string message = Anope::printf(_("[auto memo] vHost \002%s\002 has been requested by %s."), host.c_str(), source.GetNick().c_str()); MemoServ::service->Send(source.service->nick, na->GetNick(), message, true); } }
void OnResult(const LDAPResult &r) override { if (!ii->lprov) return; switch (r.type) { case QUERY_SEARCH: { if (!r.empty()) { try { const LDAPAttributes &attr = r.get(0); ii->dn = attr.get("dn"); Log(LOG_DEBUG) << "m_ldap_authenticationn: binding as " << ii->dn; ii->lprov->Bind(new IdentifyInterface(this->owner, ii), ii->dn, ii->req->GetPassword()); ii = NULL; } catch (const LDAPException &ex) { Log(this->owner) << "Error binding after search: " << ex.GetReason(); } } break; } case QUERY_BIND: { if (ii->admin_bind) { Anope::string sf = search_filter.replace_all_cs("%account", ii->req->GetAccount()).replace_all_cs("%object_class", object_class); try { Log(LOG_DEBUG) << "m_ldap_authentication: searching for " << sf; ii->lprov->Search(new IdentifyInterface(this->owner, ii), basedn, sf); ii->admin_bind = false; ii = NULL; } catch (const LDAPException &ex) { Log(this->owner) << "Unable to search for " << sf << ": " << ex.GetReason(); } } else { NickServ::Nick *na = NickServ::FindNick(ii->req->GetAccount()); if (na == NULL) { na = new NickServ::Nick(ii->req->GetAccount(), new NickServ::Account(ii->req->GetAccount())); na->SetLastRealname(ii->user ? ii->user->realname : ii->req->GetAccount()); NickServ::Event::OnNickRegister(&NickServ::Event::NickRegister::OnNickRegister, ii->user, na, ii->req->GetPassword());; ServiceBot *NickServ = Config->GetClient("NickServ"); if (ii->user && NickServ) ii->user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->GetNick().c_str()); } // encrypt and store the password in the nickcore Anope::Encrypt(ii->req->GetPassword(), na->GetAccount()->pass); na->GetAccount()->Extend<Anope::string>("m_ldap_authentication_dn", ii->dn); ii->req->Success(me); } break; } default: break; } }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { const Anope::string &nick = params[0]; Anope::string expiry = params[1]; Anope::string reason = params.size() > 2 ? params[2] : ""; time_t expiry_secs = Config->GetModule(this->GetOwner())->Get<time_t>("suspendexpire"); if (Anope::ReadOnly) source.Reply(_("Services are in read-only mode. Any changes made may not persist.")); if (expiry[0] != '+') { reason = expiry + " " + reason; reason.trim(); expiry.clear(); } else { expiry_secs = Anope::DoTime(expiry); if (expiry_secs == -1) { source.Reply(_("Invalid expiry time \002{0}\002."), expiry); return; } } NickServ::Nick *na = NickServ::FindNick(nick); if (!na) { source.Reply(_("\002{0}\002 isn't registered."), nick); return; } if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && na->GetAccount()->GetOper()) { source.Reply(_("You may not suspend other Services Operators' nicknames.")); return; } NSSuspendInfo *si = na->GetAccount()->GetRef<NSSuspendInfo *>(); if (!si) { source.Reply(_("\002%s\002 is already suspended."), na->GetAccount()->GetDisplay().c_str()); return; } NickServ::Account *nc = na->GetAccount(); si = Serialize::New<NSSuspendInfo *>(); si->SetAccount(nc); si->SetBy(source.GetNick()); si->SetReason(reason); si->SetWhen(Anope::CurTime); si->SetExpires(expiry_secs ? expiry_secs + Anope::CurTime : 0); for (NickServ::Nick *na2 : nc->GetRefs<NickServ::Nick *>()) { na2->SetLastQuit(reason); User *u2 = User::Find(na2->GetNick(), true); if (u2) { u2->Logout(); if (NickServ::service) NickServ::service->Collide(u2, na2); } } Log(LOG_ADMIN, source, this) << "for " << nick << " (" << (!reason.empty() ? reason : "No reason") << "), expires on " << (expiry_secs ? Anope::strftime(Anope::CurTime + expiry_secs) : "never"); source.Reply(_("\002{0}\002 is now suspended."), na->GetNick()); EventManager::Get()->Dispatch(&Event::NickSuspend::OnNickSuspend, na); }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { if (!this->fs) return; const Anope::string &command = params[0]; const Anope::string &subcommand = params.size() > 1 ? params[1] : ""; ForbidType ftype = FT_SIZE; if (subcommand.equals_ci("NICK")) ftype = FT_NICK; else if (subcommand.equals_ci("CHAN")) ftype = FT_CHAN; else if (subcommand.equals_ci("EMAIL")) ftype = FT_EMAIL; else if (subcommand.equals_ci("REGISTER")) ftype = FT_REGISTER; if (command.equals_ci("ADD") && params.size() > 3 && ftype != FT_SIZE) { const Anope::string &expiry = params[2][0] == '+' ? params[2] : ""; const Anope::string &entry = !expiry.empty() ? params[3] : params[2]; Anope::string reason; if (expiry.empty()) reason = params[3] + " "; if (params.size() > 4) reason += params[4]; reason.trim(); if (entry.replace_all_cs("?*", "").empty()) { source.Reply(_("The mask must contain at least one non wildcard character.")); return; } time_t expiryt = 0; if (!expiry.empty()) { expiryt = Anope::DoTime(expiry); if (expiryt == -1) { source.Reply(_("Invalid expiry time \002{0}\002."), expiry); return; } else if (expiryt) expiryt += Anope::CurTime; } NickServ::Nick *target = NickServ::FindNick(entry); if (target != NULL && Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && target->GetAccount()->IsServicesOper()) { source.Reply(_("Access denied.")); return; } ForbidData *d = this->fs->FindForbid(entry, ftype); bool created = false; if (d == NULL) { d = Serialize::New<ForbidData *>(); created = true; } d->SetMask(entry); d->SetCreator(source.GetNick()); d->SetReason(reason); d->SetCreated(Anope::CurTime); d->SetExpires(expiryt); d->SetType(ftype); if (Anope::ReadOnly) source.Reply(_("Services are in read-only mode. Any changes made may not persist.")); Log(LOG_ADMIN, source, this) << "to add a forbid on " << entry << " of type " << subcommand; source.Reply(_("Added a forbid on \002{0}\002 of type \002{1}\002 to expire on \002{2}\002."), entry, subcommand.lower(), expiryt ? Anope::strftime(expiryt, source.GetAccount()) : "never"); /* apply forbid */ switch (ftype) { case FT_NICK: { int na_matches = 0; for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) this->OnUserNickChange(it->second); for (auto it = NickServ::service->GetNickList().begin(); it != NickServ::service->GetNickList().end();) { NickServ::Nick *na = *it; ++it; d = this->fs->FindForbid(na->GetNick(), FT_NICK); if (d == NULL) continue; ++na_matches; delete na; } source.Reply(_("\002{0}\002 nickname(s) dropped."), na_matches); break; } case FT_CHAN: { int chan_matches = 0, ci_matches = 0; for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end;) { Channel *c = it->second; ++it; d = this->fs->FindForbid(c->name, FT_CHAN); if (d == NULL) continue; ServiceBot *OperServ = Config->GetClient("OperServ"); if (IRCD->CanSQLineChannel && OperServ) { time_t inhabit = Config->GetModule("chanserv")->Get<time_t>("inhabit", "15s"); #warning "xline allocated on stack" #if 0 XLine x(c->name, OperServ->nick, Anope::CurTime + inhabit, d->GetReason()); IRCD->SendSQLine(NULL, &x); #endif } else if (ChanServ::service) { ChanServ::service->Hold(c); } ++chan_matches; for (Channel::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end;) { User *u = cit->first; ++cit; if (u->server == Me || u->HasMode("OPER")) continue; reason = Anope::printf(Language::Translate(u, _("This channel has been forbidden: \002%s\002")), d->GetReason().c_str()); c->Kick(source.service, u, "%s", reason.c_str()); } } for (auto it = ChanServ::service->GetChannels().begin(); it != ChanServ::service->GetChannels().end();) { ChanServ::Channel *ci = it->second; ++it; d = this->fs->FindForbid(ci->GetName(), FT_CHAN); if (d == NULL) continue; ++ci_matches; delete ci; } source.Reply(_("\002{0}\002 channel(s) cleared, and \002{1}\002 channel(s) dropped."), chan_matches, ci_matches); break; } default: break; } } else if (command.equals_ci("DEL") && params.size() > 2 && ftype != FT_SIZE) { const Anope::string &entry = params[2]; ForbidData *d = this->fs->FindForbid(entry, ftype); if (d == nullptr) { source.Reply(_("Forbid on \002{0}\002 was not found."), entry); return; } if (Anope::ReadOnly) source.Reply(_("Services are in read-only mode. Any changes made may not persist.")); Log(LOG_ADMIN, source, this) << "to remove forbid on " << d->GetMask() << " of type " << subcommand; source.Reply(_("\002{0}\002 deleted from the \002{1}\002 forbid list."), d->GetMask(), subcommand); d->Delete(); } else if (command.equals_ci("LIST")) { const std::vector<ForbidData *> &forbids = this->fs->GetForbids(); if (forbids.empty()) { source.Reply(_("Forbid list is empty.")); return; } ListFormatter list(source.GetAccount()); list.AddColumn(_("Mask")).AddColumn(_("Type")).AddColumn(_("Creator")).AddColumn(_("Expires")).AddColumn(_("Reason")); unsigned shown = 0; for (unsigned i = 0; i < forbids.size(); ++i) { ForbidData *d = forbids[i]; if (ftype != FT_SIZE && ftype != d->GetType()) continue; Anope::string stype; if (d->GetType() == FT_NICK) stype = "NICK"; else if (d->GetType() == FT_CHAN) stype = "CHAN"; else if (d->GetType() == FT_EMAIL) stype = "EMAIL"; else if (d->GetType() == FT_REGISTER) stype = "REGISTER"; else continue; ListFormatter::ListEntry entry; entry["Mask"] = d->GetMask(); entry["Type"] = stype; entry["Creator"] = d->GetCreator(); entry["Expires"] = d->GetExpires() ? Anope::strftime(d->GetExpires(), NULL, true).c_str() : Language::Translate(source.GetAccount(), _("Never")); entry["Reason"] = d->GetReason(); list.AddEntry(entry); ++shown; } if (!shown) { source.Reply(_("There are no forbids of type \002{0}\002."), subcommand.upper()); return; } source.Reply(_("Forbid list:")); std::vector<Anope::string> replies; list.Process(replies); for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); if (shown >= forbids.size()) source.Reply(_("End of forbid list.")); else source.Reply(_("End of forbid list - \002{0}\002/\002{1}\002 entries shown."), shown, forbids.size()); } else this->OnSyntaxError(source, command); }
EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) override { if (command->name == "nickserv/confirm" && params.size() > 1) { if (Anope::ReadOnly) { source.Reply(_("Services are in read-only mode.")); return EVENT_STOP; } NickServ::Nick *na = NickServ::FindNick(params[0]); ResetInfo *ri = na ? reset.Get(na->GetAccount()) : NULL; if (na && ri) { NickServ::Account *nc = na->GetAccount(); const Anope::string &passcode = params[1]; if (ri->time < Anope::CurTime - 3600) { reset.Unset(nc); source.Reply(_("Your password reset request has expired.")); } else if (passcode.equals_cs(ri->code)) { reset.Unset(nc); nc->UnsetS<bool>("UNCONFIRMED"); Log(LOG_COMMAND, source, &commandnsresetpass) << "confirmed RESETPASS to forcefully identify as " << na->GetNick(); if (source.GetUser()) { source.GetUser()->Identify(na); source.Reply(_("You are now identified for \002{0}\002. Change your password now."), na->GetAccount()->GetDisplay()); } } else return EVENT_CONTINUE; return EVENT_STOP; } } return EVENT_CONTINUE; }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { const Anope::string &subcommand = params[0]; if (subcommand.equals_ci("ADD") && params.size() > 2) { const Anope::string &oper = params[1]; const Anope::string &otype = params[2]; if (!source.HasPriv("operserv/oper/modify")) { source.Reply(_("Access denied. You do not have the operator privilege \002{0}\002."), "operserv/oper/modify"); return; } NickServ::Nick *na = NickServ::FindNick(oper); if (na == NULL) { source.Reply(_("\002{0}\002 isn't currently online."), oper); return; } OperType *ot = OperType::Find(otype); if (ot == NULL) { source.Reply(_("Oper type \002{0}\002 has not been configured."), otype); return; } if (!HasPrivs(source, ot)) { source.Reply(_("Access denied.")); return; } Oper *o = na->GetAccount()->GetOper(); if (o != nullptr) { o->Delete(); } o = Serialize::New<Oper *>(); o->SetName(na->GetAccount()->GetDisplay()); o->SetType(ot); o->SetRequireOper(true); na->GetAccount()->SetOper(o); if (Anope::ReadOnly) source.Reply(_("Services are in read-only mode. Any changes made may not persist.")); Log(LOG_ADMIN, source, this) << "ADD " << na->GetNick() << " as type " << ot->GetName(); source.Reply("\002{0}\002 (\002{1}\002) added to the \002{2}\002 list.", na->GetNick(), na->GetAccount()->GetDisplay(), ot->GetName()); } else if (subcommand.equals_ci("DEL") && params.size() > 1) { const Anope::string &oper = params[1]; if (!source.HasPriv("operserv/oper/modify")) { source.Reply(_("Access denied. You do not have the operator privilege \002{0}\002."), "operserv/oper/modify"); return; } NickServ::Nick *na = NickServ::FindNick(oper); if (na == nullptr || na->GetAccount() == nullptr) { source.Reply(_("\002{0}\002 isn't registered."), oper); return; } Oper *o = na->GetAccount()->GetOper(); if (o == nullptr) { source.Reply(_("Nick \002{0}\002 is not a Services Operator."), oper); return; } if (!HasPrivs(source, o->GetType())) { source.Reply(_("Access denied.")); return; } o->Delete(); if (Anope::ReadOnly) source.Reply(_("Services are in read-only mode. Any changes made may not persist.")); Log(LOG_ADMIN, source, this) << "DEL " << na->GetNick(); source.Reply(_("Oper privileges removed from \002{0}\002 (\002{1}\002)."), na->GetNick(), na->GetAccount()->GetDisplay()); } else if (subcommand.equals_ci("LIST")) { source.Reply(_("Name Type")); for (NickServ::Account *nc : NickServ::service->GetAccountList()) { Oper *oper = nc->GetOper(); if (oper == nullptr) continue; source.Reply(Anope::printf("%-8s %s", oper->GetName().c_str(), oper->GetType()->GetName().c_str())); for (User *u : nc->users) source.Reply(_(" \002{0}\002 is online using this oper block."), u->nick); } } else if (subcommand.equals_ci("INFO")) { if (params.size() < 2) { source.Reply(_("Available opertypes:")); for (unsigned i = 0; i < Config->MyOperTypes.size(); ++i) { OperType *ot = Config->MyOperTypes[i]; source.Reply("%s", ot->GetName().c_str()); } return; } Anope::string fulltype = params[1]; if (params.size() > 2) fulltype += " " + params[2]; OperType *ot = OperType::Find(fulltype); if (ot == NULL) { source.Reply(_("Oper type \002{0}\002 has not been configured."), fulltype); return; } if (ot->GetCommands().empty()) { source.Reply(_("Opertype \002{0}\002 has no allowed commands."), ot->GetName()); } else { source.Reply(_("Available commands for \002{0}\002:"), ot->GetName()); Anope::string buf; std::list<Anope::string> cmds = ot->GetCommands(); for (std::list<Anope::string>::const_iterator it = cmds.begin(), it_end = cmds.end(); it != it_end; ++it) { buf += *it + " "; if (buf.length() > 400) { source.Reply("%s", buf.c_str()); buf.clear(); } } if (!buf.empty()) { source.Reply("%s", buf.c_str()); buf.clear(); } } if (ot->GetPrivs().empty()) { source.Reply(_("Opertype \002{0}\002 has no allowed privileges."), ot->GetName()); } else { source.Reply(_("Available privileges for \002{0}\002:"), ot->GetName()); Anope::string buf; std::list<Anope::string> privs = ot->GetPrivs(); for (std::list<Anope::string>::const_iterator it = privs.begin(), it_end = privs.end(); it != it_end; ++it) { buf += *it + " "; if (buf.length() > 400) { source.Reply("%s", buf.c_str()); buf.clear(); } } if (!buf.empty()) { source.Reply("%s", buf.c_str()); buf.clear(); } } if (!ot->modes.empty()) source.Reply(_("Opertype \002{0}\002 receives modes \002{1}\002 once identified."), ot->GetName(), ot->modes); } else { this->OnSyntaxError(source, subcommand); } }
void OnSuccess(NickServ::IdentifyRequest *) override { User *u = User::Find(user, true); if (!source.GetUser() || !source.service) return; NickServ::Nick *na = NickServ::FindNick(user); if (!na) return; Log(LOG_COMMAND, source, cmd) << "for " << na->GetNick(); /* Nick is being held by us, release it */ if (na->HasFieldS("HELD")) { NickServ::service->Release(na); source.Reply(_("Service's hold on \002{0}\002 has been released."), na->GetNick()); } else if (!u) { source.Reply(_("No one is using your nick, and services are not holding it.")); } // If the user being recovered is identified for the account of the nick then the user is the // same person that is executing the command, so kill them off (old GHOST command). else if (u->Account() == na->GetAccount()) { if (!source.GetAccount() && na->GetAccount()->HasFieldS("NS_SECURE")) { source.GetUser()->Login(u->Account()); Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << u->Account()->GetDisplay(); } if (Config->GetModule("ns_recover")->Get<bool>("restoreonrecover")) { if (!u->chans.empty()) { NSRecoverInfo i; for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) i[it->first->name] = it->second->status; source.GetUser()->Extend<NSRecoverInfo>("recover", i); } } u->SendMessage(*source.service, _("This nickname has been recovered by \002{0}\002. If you did not do this, then \002{0}\002 may have your password, and you should change it."), source.GetNick()); Anope::string buf = source.command.upper() + " command used by " + source.GetNick(); u->Kill(*source.service, buf); source.Reply(_("Ghost with your nick has been killed.")); if (IRCD->CanSVSNick) IRCD->SendForceNickChange(source.GetUser(), user, Anope::CurTime); } /* User is not identified or not identified to the same account as the person using this command */ else { if (!source.GetAccount() && na->GetAccount()->HasFieldS("NS_SECURE")) { source.GetUser()->Login(na->GetAccount()); // Identify the user using the command if they arent identified Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << na->GetNick() << " (" << na->GetAccount()->GetDisplay() << ")"; } u->SendMessage(*source.service, _("This nickname has been recovered by \002{0}\002."), source.GetNick()); if (NickServ::service) NickServ::service->Collide(u, na); if (IRCD->CanSVSNick) { /* If we can svsnick then release our hold and svsnick the user using the command */ if (NickServ::service) NickServ::service->Release(na); IRCD->SendForceNickChange(source.GetUser(), user, Anope::CurTime); source.Reply(_("You have regained control of \002%s\002 and are now identified as \002%s\002."), user, na->GetAccount()->GetDisplay().c_str()); } else source.Reply(_("The user with your nick has been removed. Use this command again to release services's hold on your nick.")); } }