X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmode.cpp;h=6b22587b186698d204d6700df2e4905d84bfe789;hb=7bd02d8a5dbac685d53a3f2aac9052c6ab5efa6e;hp=a89e3ae191865ca1bb40d19906e10cb30afdab10;hpb=a4fed1c1c767c8e31ffa47dc68ee7537ca28e317;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/mode.cpp b/src/mode.cpp index a89e3ae19..6b22587b1 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -387,6 +387,8 @@ void ModeParser::Process(const char** parameters, int pcnt, User *user, bool ser } else if (pcnt > 1) { + bool SkipAccessChecks = false; + if (targetchannel) { type = MODETYPE_CHANNEL; @@ -403,6 +405,7 @@ void ModeParser::Process(const char** parameters, int pcnt, User *user, bool ser FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user, NULL, targetchannel, AC_GENERAL_MODE)); if (MOD_RESULT == ACR_DENY) return; + SkipAccessChecks = (MOD_RESULT == ACR_ALLOW); } } else if (targetuser) @@ -516,7 +519,7 @@ void ModeParser::Process(const char** parameters, int pcnt, User *user, bool ser if (IS_LOCAL(user) && (MOD_RESULT == ACR_DENY)) continue; - if (IS_LOCAL(user) && (MOD_RESULT != ACR_ALLOW)) + if (!SkipAccessChecks && IS_LOCAL(user) && (MOD_RESULT != ACR_ALLOW)) { ServerInstance->Log(DEBUG,"Enter minimum prefix check"); /* Check access to this mode character */ @@ -525,24 +528,30 @@ void ModeParser::Process(const char** parameters, int pcnt, User *user, bool ser char needed = modehandlers[handler_id]->GetNeededPrefix(); ModeHandler* prefixmode = FindPrefix(needed); ServerInstance->Log(DEBUG,"Needed prefix: %c", needed); - if (prefixmode) + + /* If the mode defined by the handler is not '\0', but the handler for it + * cannot be found, they probably dont have the right module loaded to implement + * the prefix they want to compare the mode against, e.g. '&' for m_chanprotect. + * Revert to checking against the minimum core prefix, '%'. + */ + if (needed && !prefixmode) + prefixmode = FindPrefix('%'); + + unsigned int neededrank = prefixmode->GetPrefixRank(); + /* Compare our rank on the channel against the rank of the required prefix, + * allow if >= ours. Because mIRC and xchat throw a tizz if the modes shown + * in NAMES(X) are not in rank order, we know the most powerful mode is listed + * first, so we don't need to iterate, we just look up the first instead. + */ + std::string modestring = targetchannel->GetAllPrefixChars(user); + char ml = (modestring.empty() ? '\0' : modestring[0]); + ModeHandler* ourmode = FindPrefix(ml); + if (!ourmode || ourmode->GetPrefixRank() < neededrank) { - unsigned int neededrank = prefixmode->GetPrefixRank(); - /* Compare our rank on the channel against the rank of the required prefix, - * allow if >= ours. Because mIRC and xchat throw a tizz if the modes shown - * in NAMES(X) are not in rank order, we know the most powerful mode is listed - * first, so we don't need to iterate, we just look up the first instead. - */ - std::string modestring = targetchannel->GetAllPrefixChars(user); - char ml = (modestring.empty() ? '\0' : modestring[0]); - ModeHandler* ourmode = FindPrefix(ml); - if (!ourmode || ourmode->GetPrefixRank() < neededrank) - { - /* Bog off */ - user->WriteServ("482 %s %s :You require channel privilege '%c' or above to execute channel mode '%c'", - user->nick, targetchannel->name, needed, modechar); - continue; - } + /* Bog off */ + user->WriteServ("482 %s %s :You must have channel privilege %c or above to %sset channel mode %c", + user->nick, targetchannel->name, needed, adding ? "" : "un", modechar); + continue; } } }