From 2a022cb9b7ed10d929beb96b6fcc2f1aa6a910f3 Mon Sep 17 00:00:00 2001
From: Peter Powell <petpow@saberuk.com>
Date: Tue, 10 Jul 2018 20:32:08 +0100
Subject: Add a silent option to <options:restrictbannedusers>.

This is useful when dealing with spambots that switch method when
they receive ERR_CANNOTSENDTOCHAN.
---
 src/configreader.cpp                | 11 ++++++++++-
 src/coremods/core_privmsg.cpp       |  5 +++--
 src/coremods/core_user/cmd_nick.cpp |  7 ++++---
 3 files changed, 17 insertions(+), 6 deletions(-)

(limited to 'src')

diff --git a/src/configreader.cpp b/src/configreader.cpp
index c9fa62510..b5d6b3ecb 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -434,7 +434,6 @@ void ServerConfig::Fill()
 	HideServer = security->getString("hideserver", security->getString("hidewhois"));
 	HideKillsServer = security->getString("hidekills");
 	HideULineKills = security->getBool("hideulinekills");
-	RestrictBannedUsers = security->getBool("restrictbannedusers", true);
 	GenericOper = security->getBool("genericoper");
 	SyntaxHints = options->getBool("syntaxhints");
 	CycleHostsFromUser = options->getBool("cyclehostsfromuser");
@@ -474,6 +473,16 @@ void ServerConfig::Fill()
 	ReadXLine(this, "badhost", "host", ServerInstance->XLines->GetFactory("K"));
 	ReadXLine(this, "exception", "host", ServerInstance->XLines->GetFactory("E"));
 
+	const std::string restrictbannedusers = options->getString("restrictbannedusers", "yes");
+	if (stdalgo::string::equalsci(restrictbannedusers, "no"))
+		RestrictBannedUsers = ServerConfig::BUT_NORMAL;
+	else if (stdalgo::string::equalsci(restrictbannedusers, "silent"))
+		RestrictBannedUsers = ServerConfig::BUT_RESTRICT_SILENT;
+	else if (stdalgo::string::equalsci(restrictbannedusers, "yes"))
+		RestrictBannedUsers =  ServerConfig::BUT_RESTRICT_NOTIFY;
+	else
+		throw CoreException(restrictbannedusers + " is an invalid <options:restrictbannedusers> value, at " + options->getTagLocation());
+
 	DisabledUModes.reset();
 	std::string modes = ConfValue("disabled")->getString("usermodes");
 	for (std::string::const_iterator p = modes.begin(); p != modes.end(); ++p)
diff --git a/src/coremods/core_privmsg.cpp b/src/coremods/core_privmsg.cpp
index 6c5b7557e..29756a4c2 100644
--- a/src/coremods/core_privmsg.cpp
+++ b/src/coremods/core_privmsg.cpp
@@ -141,11 +141,12 @@ CmdResult MessageCommandBase::HandleMessage(const std::vector<std::string>& para
 					return CMD_FAILURE;
 				}
 
-				if (ServerInstance->Config->RestrictBannedUsers)
+				if (ServerInstance->Config->RestrictBannedUsers != ServerConfig::BUT_NORMAL)
 				{
 					if (chan->IsBanned(user))
 					{
-						user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (you're banned)");
+						if (ServerInstance->Config->RestrictBannedUsers == ServerConfig::BUT_RESTRICT_NOTIFY)
+							user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (you're banned)");
 						return CMD_FAILURE;
 					}
 				}
diff --git a/src/coremods/core_user/cmd_nick.cpp b/src/coremods/core_user/cmd_nick.cpp
index 672155741..80bfbe674 100644
--- a/src/coremods/core_user/cmd_nick.cpp
+++ b/src/coremods/core_user/cmd_nick.cpp
@@ -70,15 +70,16 @@ CmdResult CommandNick::HandleLocal(const std::vector<std::string>& parameters, L
 
 	// Disallow the nick change if <security:restrictbannedusers> is on and there is a ban matching this user in
 	// one of the channels they are on
-	if (ServerInstance->Config->RestrictBannedUsers)
+	if (ServerInstance->Config->RestrictBannedUsers != ServerConfig::BUT_NORMAL)
 	{
 		for (User::ChanList::iterator i = user->chans.begin(); i != user->chans.end(); ++i)
 		{
 			Channel* chan = (*i)->chan;
 			if (chan->GetPrefixValue(user) < VOICE_VALUE && chan->IsBanned(user))
 			{
-				user->WriteNumeric(ERR_CANTCHANGENICK, InspIRCd::Format("Cannot change nickname while on %s (you're banned)",
-					chan->name.c_str()));
+				if (ServerInstance->Config->RestrictBannedUsers == ServerConfig::BUT_RESTRICT_NOTIFY)
+					user->WriteNumeric(ERR_CANTCHANGENICK, InspIRCd::Format("Cannot change nickname while on %s (you're banned)",
+						chan->name.c_str()));
 				return CMD_FAILURE;
 			}
 		}
-- 
cgit v1.2.3