summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/inspircd.conf.example3
-rw-r--r--docs/modules.conf.example9
-rw-r--r--include/inspircd.h10
-rw-r--r--include/modules.h8
-rw-r--r--src/channels.cpp3
-rw-r--r--src/helperfuncs.cpp25
-rw-r--r--src/inspircd.cpp3
-rw-r--r--src/modules.cpp1
-rw-r--r--src/modules/m_blockcaps.cpp3
-rw-r--r--src/modules/m_blockcolor.cpp3
-rw-r--r--src/modules/m_censor.cpp3
-rw-r--r--src/modules/m_chanfilter.cpp3
-rw-r--r--src/modules/m_exemptchanops.cpp95
-rw-r--r--src/modules/m_messageflood.cpp3
-rw-r--r--src/modules/m_nickflood.cpp4
-rw-r--r--src/modules/m_noctcp.cpp3
-rw-r--r--src/modules/m_nonicks.cpp3
-rw-r--r--src/modules/m_nonotice.cpp2
-rw-r--r--src/modules/m_services_account.cpp3
-rw-r--r--src/modules/m_stripcolor.cpp3
-rw-r--r--src/modules/m_testnet.cpp1
21 files changed, 102 insertions, 89 deletions
diff --git a/docs/inspircd.conf.example b/docs/inspircd.conf.example
index b3928712c..a292905c8 100644
--- a/docs/inspircd.conf.example
+++ b/docs/inspircd.conf.example
@@ -580,6 +580,9 @@
# moronbanner: This is the text that is sent to a user when they are
# banned from the server.
moronbanner="You're banned! Email haha@abuse.com with the ERROR line below for help."
+
+ # exemptchanops: exemptions for channel access restrictions based on prefix.
+ exemptchanops="nonick:v flood:o"
# invitebypassmodes: This allows /invite to bypass other channel modes.
# (Such as +k, +j, +l, etc)
diff --git a/docs/modules.conf.example b/docs/modules.conf.example
index db4b1db52..02d80431d 100644
--- a/docs/modules.conf.example
+++ b/docs/modules.conf.example
@@ -735,15 +735,6 @@
# modes are blockcaps, noctcp, blockcolor, nickflood, flood, censor, #
# filter, regmoderated, nonick, nonotice, and stripcolor. #
#<module name="m_exemptchanops.so"> #
-# #
-#-#-#-#-#-#-#-#-#-#- EXEMPTCHANOPS CONFIGURATION -#-#-#-#-#-#-#-#-#-#
-# defaults - default exemptions. These can be added to or overridden #
-# by the channel mode +X. Each item is of the form #
-# [mode]:[minstatus] where you must have [minstatus] in #
-# order to be able to bypass [mode]. #
-# Use "blockcolor:*" to override a default exemption #
-#<exemptchanops defaults="nonick:v flood:o">
-
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# Filter module: Provides message filtering, similar to SPAMFILTER.
diff --git a/include/inspircd.h b/include/inspircd.h
index a9a1af482..d973fb66c 100644
--- a/include/inspircd.h
+++ b/include/inspircd.h
@@ -77,7 +77,6 @@ CoreExport extern InspIRCd* ServerInstance;
#include "socketengine.h"
#include "snomasks.h"
#include "filelogger.h"
-#include "caller.h"
#include "modules.h"
#include "threadengine.h"
#include "configreader.h"
@@ -240,6 +239,7 @@ DEFINE_HANDLER1(FloodQuitUserHandler, void, User*);
DEFINE_HANDLER2(IsChannelHandler, bool, const char*, size_t);
DEFINE_HANDLER1(IsSIDHandler, bool, const std::string&);
DEFINE_HANDLER1(RehashHandler, void, const std::string&);
+DEFINE_HANDLER3(OnCheckExemptionHandler, ModResult, User*, Channel*, const std::string&);
/** The main class of the irc server.
* This class contains instances of all the other classes in this software.
@@ -308,6 +308,7 @@ class CoreExport InspIRCd
IsNickHandler HandleIsNick;
IsIdentHandler HandleIsIdent;
FloodQuitUserHandler HandleFloodQuitUser;
+ OnCheckExemptionHandler HandleOnCheckExemption;
IsChannelHandler HandleIsChannel;
IsSIDHandler HandleIsSID;
RehashHandler HandleRehash;
@@ -782,6 +783,13 @@ class CoreExport InspIRCd
*/
caller1<void, User*> FloodQuitUser;
+ /** Called to check whether a channel restriction mode applies to a user
+ * @param User that is attempting some action
+ * @param Channel that the action is being performed on
+ * @param Action name
+ */
+ caller3<ModResult, User*, Channel*, const std::string&> OnCheckExemption;
+
/** Restart the server.
* This function will not return. If an error occurs,
* it will throw an instance of CoreException.
diff --git a/include/modules.h b/include/modules.h
index 4f60d55e4..71cbc8480 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -327,7 +327,7 @@ enum Implementation
I_OnPostOper, I_OnSyncNetwork, I_OnSetAway, I_OnPostCommand, I_OnPostJoin,
I_OnWhoisLine, I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass,
I_OnText, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnHookIO,
- I_OnPreRehash, I_OnModuleRehash, I_OnSendWhoLine, I_OnChangeIdent, I_OnChannelRestrictionApply,
+ I_OnPreRehash, I_OnModuleRehash, I_OnSendWhoLine, I_OnChangeIdent,
I_END
};
@@ -1278,12 +1278,6 @@ class CoreExport Module : public classbase, public usecountbase
* @param line The raw line to send; modifiable, if empty no line will be returned.
*/
virtual void OnSendWhoLine(User* source, const std::vector<std::string>& params, User* user, Channel* channel, std::string& line);
-
- /** Called to check whether a channel restriction mode applies to a user on it
- * @return MOD_RES_DENY to apply the restriction, MOD_RES_ALLOW to bypass
- * the restriction, or MOD_RES_PASSTHRU to check restriction status normally
- */
- virtual ModResult OnChannelRestrictionApply(User* user, Channel* chan, const char* restriction);
};
diff --git a/src/channels.cpp b/src/channels.cpp
index d0533aee6..5603ef1dd 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -92,9 +92,8 @@ int Channel::SetTopic(User *u, std::string &ntopic, bool forceset)
return CMD_FAILURE;
if (res != MOD_RES_ALLOW)
{
- FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (u,this,"topiclock"));
bool defok = IsModeSet('t') ? GetPrefixValue(u) >= HALFOP_VALUE : HasUser(u);
- if (!res.check(defok))
+ if (!ServerInstance->OnCheckExemption(u,this,"topiclock").check(defok))
{
if (!this->HasUser(u))
u->WriteNumeric(442, "%s %s :You're not on that channel!",u->nick.c_str(), this->name.c_str());
diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp
index 66a84bbce..98dd1fc7f 100644
--- a/src/helperfuncs.cpp
+++ b/src/helperfuncs.cpp
@@ -439,3 +439,28 @@ void GenRandomHandler::Call(char *output, size_t max)
for(unsigned int i=0; i < max; i++)
output[i] = random();
}
+
+ModResult OnCheckExemptionHandler::Call(User* user, Channel* chan, const std::string& restriction)
+{
+ unsigned int mypfx = chan->GetPrefixValue(user);
+ char minmode;
+ std::string current;
+
+ irc::spacesepstream defaultstream(ServerInstance->Config->ConfValue("options")->getString("exemptchanops"));
+
+ while (defaultstream.GetToken(current))
+ {
+ std::string::size_type pos = current.find(':');
+ if (pos == std::string::npos)
+ continue;
+ if (current.substr(0,pos) == restriction)
+ minmode = current[pos+1];
+ }
+
+ ModeHandler* mh = ServerInstance->Modes->FindMode(minmode, MODETYPE_CHANNEL);
+ if (mh && mypfx >= mh->GetPrefixRank())
+ return MOD_RES_ALLOW;
+ if (mh || minmode == '*')
+ return MOD_RES_DENY;
+ return MOD_RES_PASSTHRU;
+}
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 27060be52..c6faf8802 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -305,7 +305,8 @@ InspIRCd::InspIRCd(int argc, char** argv) :
Rehash(&HandleRehash),
IsNick(&HandleIsNick),
IsIdent(&HandleIsIdent),
- FloodQuitUser(&HandleFloodQuitUser)
+ FloodQuitUser(&HandleFloodQuitUser),
+ OnCheckExemption(&HandleOnCheckExemption)
{
#ifdef WIN32
// Strict, frequent checking of memory on debug builds
diff --git a/src/modules.cpp b/src/modules.cpp
index 98788c616..83393c2ad 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -163,7 +163,6 @@ ModResult Module::OnNumeric(User*, unsigned int, const std::string&) { return MO
void Module::OnHookIO(StreamSocket*, ListenSocket*) { }
ModResult Module::OnAcceptConnection(int, ListenSocket*, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { return MOD_RES_PASSTHRU; }
void Module::OnSendWhoLine(User*, const std::vector<std::string>&, User*, Channel*, std::string&) { }
-ModResult Module::OnChannelRestrictionApply(User*, Channel*, const char*) { return MOD_RES_PASSTHRU; }
ModuleManager::ModuleManager() : ModCount(0)
{
diff --git a/src/modules/m_blockcaps.cpp b/src/modules/m_blockcaps.cpp
index ade42cb4b..873cf46ca 100644
--- a/src/modules/m_blockcaps.cpp
+++ b/src/modules/m_blockcaps.cpp
@@ -59,8 +59,7 @@ public:
return MOD_RES_PASSTHRU;
Channel* c = (Channel*)dest;
- ModResult res;
- FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"blockcaps"));
+ ModResult res = ServerInstance->OnCheckExemption(user,c,"blockcaps");
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;
diff --git a/src/modules/m_blockcolor.cpp b/src/modules/m_blockcolor.cpp
index 9ffb36b80..d19317074 100644
--- a/src/modules/m_blockcolor.cpp
+++ b/src/modules/m_blockcolor.cpp
@@ -47,8 +47,7 @@ class ModuleBlockColour : public Module
if ((target_type == TYPE_CHANNEL) && (IS_LOCAL(user)))
{
Channel* c = (Channel*)dest;
- ModResult res;
- FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"blockcolor"));
+ ModResult res = ServerInstance->OnCheckExemption(user,c,"blockcolor");
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;
diff --git a/src/modules/m_censor.cpp b/src/modules/m_censor.cpp
index 6a9f6941f..bf1f0225d 100644
--- a/src/modules/m_censor.cpp
+++ b/src/modules/m_censor.cpp
@@ -76,8 +76,7 @@ class ModuleCensor : public Module
{
active = ((Channel*)dest)->IsModeSet('G');
Channel* c = (Channel*)dest;
- ModResult res;
- FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"censor"));
+ ModResult res = ServerInstance->OnCheckExemption(user,c,"censor");
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;
diff --git a/src/modules/m_chanfilter.cpp b/src/modules/m_chanfilter.cpp
index e790a15d8..faa064dbf 100644
--- a/src/modules/m_chanfilter.cpp
+++ b/src/modules/m_chanfilter.cpp
@@ -83,8 +83,7 @@ class ModuleChanFilter : public Module
virtual ModResult ProcessMessages(User* user,Channel* chan,std::string &text)
{
- ModResult res;
- FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,chan,"filter"));
+ ModResult res = ServerInstance->OnCheckExemption(user,chan,"filter");
if (!IS_LOCAL(user) || res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;
diff --git a/src/modules/m_exemptchanops.cpp b/src/modules/m_exemptchanops.cpp
index 2677e66df..e92350eeb 100644
--- a/src/modules/m_exemptchanops.cpp
+++ b/src/modules/m_exemptchanops.cpp
@@ -52,42 +52,12 @@ class ExemptChanOps : public ListModeBase
}
};
-class ModuleExemptChanOps : public Module
+class ExemptHandler : public HandlerBase3<ModResult, User*, Channel*, const std::string&>
{
- ExemptChanOps ec;
- std::string defaults;
-
public:
-
- ModuleExemptChanOps() : ec(this)
- {
- }
-
- void init()
- {
- ServerInstance->Modules->AddService(ec);
- Implementation eventlist[] = { I_OnChannelDelete, I_OnChannelRestrictionApply, I_OnRehash, I_OnSyncChannel };
- ServerInstance->Modules->Attach(eventlist, this, 4);
-
- OnRehash(NULL);
- }
-
- Version GetVersion()
- {
- return Version("Provides the ability to allow channel operators to be exempt from certain modes.",VF_VENDOR);
- }
-
- void OnRehash(User* user)
- {
- defaults = ServerInstance->Config->ConfValue("exemptchanops")->getString("defaults");
- ec.DoRehash();
- }
-
- void OnSyncChannel(Channel* chan, Module* proto, void* opaque)
- {
- ec.DoSyncChannel(chan, proto, opaque);
- }
-
+ ExemptChanOps ec;
+ ExemptHandler(Module* me) : ec(me) {}
+
ModeHandler* FindMode(const std::string& mid)
{
if (mid.length() == 1)
@@ -101,21 +71,11 @@ class ModuleExemptChanOps : public Module
return NULL;
}
- ModResult OnChannelRestrictionApply(User* user, Channel* chan, const char* restriction)
+ ModResult Call(User* user, Channel* chan, const std::string& restriction)
{
unsigned int mypfx = chan->GetPrefixValue(user);
- irc::spacesepstream defaultstream(defaults);
std::string minmode;
- std::string current;
- while (defaultstream.GetToken(current))
- {
- std::string::size_type pos = current.find(':');
- if (pos == std::string::npos)
- continue;
- if (current.substr(0,pos) == restriction)
- minmode = current[pos+1];
- }
modelist* list = ec.extItem.get(chan);
if (list)
@@ -135,7 +95,50 @@ class ModuleExemptChanOps : public Module
return MOD_RES_ALLOW;
if (mh || minmode == "*")
return MOD_RES_DENY;
- return MOD_RES_PASSTHRU;
+
+ return ServerInstance->HandleOnCheckExemption.Call(user, chan, restriction);
+ }
+};
+
+class ModuleExemptChanOps : public Module
+{
+ std::string defaults;
+ ExemptHandler eh;
+
+ public:
+
+ ModuleExemptChanOps() : eh(this)
+ {
+ }
+
+ void init()
+ {
+ ServerInstance->Modules->AddService(eh.ec);
+ Implementation eventlist[] = { I_OnRehash, I_OnSyncChannel };
+ ServerInstance->Modules->Attach(eventlist, this, 2);
+ ServerInstance->OnCheckExemption = &eh;
+
+ OnRehash(NULL);
+ }
+
+ ~ModuleExemptChanOps()
+ {
+ ServerInstance->OnCheckExemption = &ServerInstance->HandleOnCheckExemption;
+ }
+
+ Version GetVersion()
+ {
+ return Version("Provides the ability to allow channel operators to be exempt from certain modes.",VF_VENDOR);
+ }
+
+ void OnRehash(User* user)
+ {
+ eh.ec.DoRehash();
+ }
+
+ void OnSyncChannel(Channel* chan, Module* proto, void* opaque)
+ {
+ eh.ec.DoSyncChannel(chan, proto, opaque);
}
};
diff --git a/src/modules/m_messageflood.cpp b/src/modules/m_messageflood.cpp
index c37537249..ccaf0a402 100644
--- a/src/modules/m_messageflood.cpp
+++ b/src/modules/m_messageflood.cpp
@@ -196,8 +196,7 @@ class ModuleMsgFlood : public Module
ModResult ProcessMessages(User* user,Channel* dest, const std::string &text)
{
- ModResult res;
- FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,dest,"flood"));
+ ModResult res = ServerInstance->OnCheckExemption(user,dest,"flood");
if (!IS_LOCAL(user) || res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;
diff --git a/src/modules/m_nickflood.cpp b/src/modules/m_nickflood.cpp
index 47c8bc836..708d30e6b 100644
--- a/src/modules/m_nickflood.cpp
+++ b/src/modules/m_nickflood.cpp
@@ -209,7 +209,7 @@ class ModuleNickFlood : public Module
nickfloodsettings *f = nf.ext.get(channel);
if (f)
{
- FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,channel,"nickflood"));
+ res = ServerInstance->OnCheckExemption(user,channel,"nickflood");
if (res == MOD_RES_ALLOW)
continue;
@@ -248,7 +248,7 @@ class ModuleNickFlood : public Module
nickfloodsettings *f = nf.ext.get(channel);
if (f)
{
- FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,channel,"nickflood"));
+ res = ServerInstance->OnCheckExemption(user,channel,"nickflood");
if (res == MOD_RES_ALLOW)
return;
diff --git a/src/modules/m_noctcp.cpp b/src/modules/m_noctcp.cpp
index 19f97b42c..680392ea9 100644
--- a/src/modules/m_noctcp.cpp
+++ b/src/modules/m_noctcp.cpp
@@ -78,8 +78,7 @@ class ModuleNoCTCP : public Module
if ((target_type == TYPE_CHANNEL) && (IS_LOCAL(user)))
{
Channel* c = (Channel*)dest;
- ModResult res;
- FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"noctcp"));
+ ModResult res = ServerInstance->OnCheckExemption(user,c,"noctcp");
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;
diff --git a/src/modules/m_nonicks.cpp b/src/modules/m_nonicks.cpp
index 8713ffe96..7a6d3ffd0 100644
--- a/src/modules/m_nonicks.cpp
+++ b/src/modules/m_nonicks.cpp
@@ -84,8 +84,7 @@ class ModuleNoNickChange : public Module
{
Channel* curr = *i;
- ModResult res;
- FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,curr,"nonick"));
+ ModResult res = ServerInstance->OnCheckExemption(user,curr,"nonick");
if (res == MOD_RES_ALLOW)
continue;
diff --git a/src/modules/m_nonotice.cpp b/src/modules/m_nonotice.cpp
index fe1e0a46d..b3f3d8da6 100644
--- a/src/modules/m_nonotice.cpp
+++ b/src/modules/m_nonotice.cpp
@@ -53,7 +53,7 @@ class ModuleNoNotice : public Module
// ulines are exempt.
return MOD_RES_PASSTHRU;
}
- FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"nonotice"));
+ res = ServerInstance->OnCheckExemption(user,c,"nonotice");
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;
else
diff --git a/src/modules/m_services_account.cpp b/src/modules/m_services_account.cpp
index 4b047ea07..61026c08f 100644
--- a/src/modules/m_services_account.cpp
+++ b/src/modules/m_services_account.cpp
@@ -175,8 +175,7 @@ class ModuleServicesAccount : public Module
if (target_type == TYPE_CHANNEL)
{
Channel* c = (Channel*)dest;
- ModResult res;
- FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"regmoderated"));
+ ModResult res = ServerInstance->OnCheckExemption(user,c,"regmoderated");
if (c->IsModeSet('M') && !is_registered && res != MOD_RES_ALLOW)
{
diff --git a/src/modules/m_stripcolor.cpp b/src/modules/m_stripcolor.cpp
index 113c931cb..c2246a0d9 100644
--- a/src/modules/m_stripcolor.cpp
+++ b/src/modules/m_stripcolor.cpp
@@ -114,8 +114,7 @@ class ModuleStripColor : public Module
else if (target_type == TYPE_CHANNEL)
{
Channel* t = (Channel*)dest;
- ModResult res;
- FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,t,"stripcolor"));
+ ModResult res = ServerInstance->OnCheckExemption(user,t,"stripcolor");
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;
diff --git a/src/modules/m_testnet.cpp b/src/modules/m_testnet.cpp
index faa0c7b2e..2f514cf0b 100644
--- a/src/modules/m_testnet.cpp
+++ b/src/modules/m_testnet.cpp
@@ -169,7 +169,6 @@ static void checkall(Module* noimpl)
CHK(OnModuleRehash);
CHK(OnSendWhoLine);
CHK(OnChangeIdent);
- CHK(OnChannelRestrictionApply);
}
class CommandTest : public Command