aboutsummaryrefslogtreecommitdiffstats
path: root/src/mode.cpp
diff options
context:
space:
mode:
authorGravatar brain2008-02-14 18:24:28 +0000
committerGravatar brain2008-02-14 18:24:28 +0000
commit91a8894d5d4637ad6aea33ad77af67445d548732 (patch)
tree1900d40f30f8e871502710bdd7950aaa35bd9531 /src/mode.cpp
parentSomebody *eyes a certain norwegian wannabe* defined two commands called WATCH... (diff)
New mode stuff. Note, the framework is now here so that every mode handler can state what prefix is required to execute it. For example: You can say that mode +j needs '%' to execute it, so that
then only a halfop or above can use mode +j. If you put '@' in this member value, only ops and above can use it. The OnRawMode can return ACR_ALLOW on a case by case basis to totally override this check against the prefix char. If you return ACR_DEFAULT the check goes ahead. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@8935 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src/mode.cpp')
-rw-r--r--src/mode.cpp69
1 files changed, 51 insertions, 18 deletions
diff --git a/src/mode.cpp b/src/mode.cpp
index 4d0a812e8..3fad8627d 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -54,8 +54,8 @@
/* +n (notice mask - our implementation of snomasks) */
#include "modes/umode_n.h"
-ModeHandler::ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix)
- : ServerInstance(Instance), mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), oper(operonly), prefix(mprefix), count(0)
+ModeHandler::ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix, char prefixrequired)
+ : ServerInstance(Instance), mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), oper(operonly), prefix(mprefix), count(0), prefixneeded(prefixrequired)
{
}
@@ -68,6 +68,16 @@ bool ModeHandler::IsListMode()
return list;
}
+char ModeHandler::GetNeededPrefix()
+{
+ return prefixneeded;
+}
+
+void ModeHandler::SetNeededPrefix(char needsprefix)
+{
+ prefixneeded = needsprefix;
+}
+
unsigned int ModeHandler::GetPrefixRank()
{
return 0;
@@ -386,28 +396,13 @@ void ModeParser::Process(const char** parameters, int pcnt, User *user, bool ser
* (e.g. are they a (half)op?
*/
- if ((IS_LOCAL(user)) && (targetchannel->GetStatus(user) < STATUS_HOP))
+ if ((IS_LOCAL(user)) && (!ServerInstance->ULine(user->server)) && (!servermode))
{
/* We don't have halfop */
int MOD_RESULT = 0;
FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user, NULL, targetchannel, AC_GENERAL_MODE));
if (MOD_RESULT == ACR_DENY)
return;
-
- if (MOD_RESULT == ACR_DEFAULT)
- {
- /* Are we a uline or is it a servermode? */
- if ((!ServerInstance->ULine(user->server)) && (!servermode))
- {
- /* Not enough permission:
- * NOT a uline and NOT a servermode,
- * OR, NOT halfop or above.
- */
- user->WriteServ("482 %s %s :You're not a channel %soperator",user->nick, targetchannel->name,
- ServerInstance->Config->AllowHalfop ? "(half)" : "");
- return;
- }
- }
}
}
else if (targetuser)
@@ -509,11 +504,49 @@ void ModeParser::Process(const char** parameters, int pcnt, User *user, bool ser
continue;
}
+
int MOD_RESULT = 0;
FOREACH_RESULT(I_OnRawMode, OnRawMode(user, targetchannel, modechar, parameter, adding, 1));
if (MOD_RESULT == ACR_DENY)
continue;
+ if (MOD_RESULT != ACR_ALLOW)
+ {
+ /* Check access to this mode character */
+ if ((type == MODETYPE_CHANNEL) && (modehandlers[handler_id]->GetNeededPrefix()))
+ {
+ bool allowed = false;
+ char needed = modehandlers[handler_id]->GetNeededPrefix();
+ ModeHandler* prefixmode = FindPrefix(needed);
+ if (prefixmode)
+ {
+ unsigned int neededrank = prefixmode->GetPrefixRank();
+
+ /* Compare our rank on the channel against the rank of the required prefix,
+ * allow if >= ours
+ */
+
+ std::string modestring = ModeString(user, targetchannel);
+ for (std::string::iterator v = modestring.begin(); v != modestring.end(); ++v)
+ {
+ ModeHandler* ourmode = FindPrefix(*v);
+ if (ourmode && (ourmode->GetPrefixRank() >= neededrank))
+ {
+ /* Yay, allowed */
+ allowed = true;
+ break;
+ }
+ }
+ }
+
+ if (!allowed)
+ {
+ user->WriteServ("482 %s %s :You require channel privilege '%c' or above to execute channel mode '%c'",user->nick,
+ targetchannel->name, needed, modechar);
+ }
+ }
+ }
+
bool had_parameter = !parameter.empty();
for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++)