Beispiel #1
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) 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);
	}
Beispiel #2
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) 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();
	}
Beispiel #3
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) 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);
		}
	}
Beispiel #4
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) 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");
	}
Beispiel #5
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) 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") << ")";
	}
Beispiel #6
0
    void Execute(CommandSource &source, const std::vector<Anope::string> &params) 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());
        }
    }
Beispiel #7
0
	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);
			}
	}
Beispiel #8
0
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);
		}
}
Beispiel #9
0
	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;
		}
	}
Beispiel #10
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) 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);
	}
Beispiel #11
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) 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);
	}
Beispiel #12
0
    EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) 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;
    }
Beispiel #13
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) 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);
		}
	}
Beispiel #14
0
	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."));
		}
	}