diff options
-rw-r--r-- | include/modes/cmode_h.h | 2 | ||||
-rw-r--r-- | include/modes/cmode_o.h | 2 | ||||
-rw-r--r-- | include/modes/cmode_v.h | 2 | ||||
-rw-r--r-- | include/modules.h | 58 | ||||
-rw-r--r-- | src/channels.cpp | 33 | ||||
-rw-r--r-- | src/mode.cpp | 7 | ||||
-rw-r--r-- | src/modes/cmode_h.cpp | 78 | ||||
-rw-r--r-- | src/modes/cmode_o.cpp | 77 | ||||
-rw-r--r-- | src/modes/cmode_v.cpp | 77 | ||||
-rw-r--r-- | src/modules.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_chanprotect.cpp | 105 | ||||
-rw-r--r-- | src/modules/m_nokicks.cpp | 33 | ||||
-rw-r--r-- | src/modules/m_ojoin.cpp | 50 | ||||
-rw-r--r-- | src/modules/m_override.cpp | 132 | ||||
-rw-r--r-- | src/modules/m_samode.cpp | 10 |
15 files changed, 86 insertions, 582 deletions
diff --git a/include/modes/cmode_h.h b/include/modes/cmode_h.h index cd6d260f4..dd188626c 100644 --- a/include/modes/cmode_h.h +++ b/include/modes/cmode_h.h @@ -24,8 +24,6 @@ class ModeChannelHalfOp : public ModeHandler public: ModeChannelHalfOp(InspIRCd* Instance); ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding); - std::string AddHalfOp(User *user,const char *dest,Channel *chan,int status); - std::string DelHalfOp(User *user,const char *dest,Channel *chan,int status); ModePair ModeSet(User* source, User* dest, Channel* channel, const std::string ¶meter); unsigned int GetPrefixRank(); void RemoveMode(Channel* channel, irc::modestacker* stack = NULL); diff --git a/include/modes/cmode_o.h b/include/modes/cmode_o.h index f0b3154e2..60772eb5f 100644 --- a/include/modes/cmode_o.h +++ b/include/modes/cmode_o.h @@ -24,8 +24,6 @@ class ModeChannelOp : public ModeHandler public: ModeChannelOp(InspIRCd* Instance); ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding); - std::string AddOp(User *user,const char *dest,Channel *chan,int status); - std::string DelOp(User *user,const char *dest,Channel *chan,int status); ModePair ModeSet(User* source, User* dest, Channel* channel, const std::string ¶meter); unsigned int GetPrefixRank(); void RemoveMode(Channel* channel, irc::modestacker* stack = NULL); diff --git a/include/modes/cmode_v.h b/include/modes/cmode_v.h index 06a6ce5a5..26304d64d 100644 --- a/include/modes/cmode_v.h +++ b/include/modes/cmode_v.h @@ -24,8 +24,6 @@ class ModeChannelVoice : public ModeHandler public: ModeChannelVoice(InspIRCd* Instance); ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding); - std::string AddVoice(User *user,const char *dest,Channel *chan,int status); - std::string DelVoice(User *user,const char *dest,Channel *chan,int status); ModePair ModeSet(User* source, User* dest, Channel* channel, const std::string ¶meter); unsigned int GetPrefixRank(); void RemoveMode(User* user, irc::modestacker* stack = NULL); diff --git a/include/modules.h b/include/modules.h index 0fdecbe15..9c8fa395a 100644 --- a/include/modules.h +++ b/include/modules.h @@ -27,24 +27,6 @@ class XLine; -/** Used with OnAccessCheck() method of modules - */ -enum AccessControlType { - ACR_DEFAULT, // Do default action (act as if the module isnt even loaded) - ACR_DENY, // deny the action - ACR_ALLOW, // allow the action - AC_KICK, // a user is being kicked - AC_DEOP, // a user is being deopped - AC_OP, // a user is being opped - AC_VOICE, // a user is being voiced - AC_DEVOICE, // a user is being devoiced - AC_HALFOP, // a user is being halfopped - AC_DEHALFOP, // a user is being dehalfopped - AC_INVITE, // a user is being invited - AC_GENERAL_MODE, // a channel mode is being changed - AC_GENERAL_UMODE // a user mode is being changed -}; - /** Used to define a set of behavior bits for a module */ enum ModuleFlags { @@ -419,7 +401,7 @@ enum Implementation I_OnUserMessage, I_OnUserNotice, I_OnMode, I_OnGetServerDescription, I_OnSyncUser, I_OnSyncChannel, I_OnDecodeMetaData, I_OnWallops, I_OnChangeHost, I_OnChangeName, I_OnAddLine, I_OnDelLine, I_OnExpireLine, I_OnCleanup, - I_OnUserPostNick, I_OnAccessCheck, I_On005Numeric, I_OnKill, I_OnRemoteKill, I_OnLoadModule, + I_OnUserPostNick, I_OnPreMode, I_On005Numeric, I_OnKill, I_OnRemoteKill, I_OnLoadModule, I_OnUnloadModule, I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite, I_OnRawMode, I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckExtBan, I_OnCheckStringExtBan, I_OnStats, I_OnChangeLocalUserHost, I_OnChangeLocalUserGecos, I_OnPreTopicChange, @@ -954,32 +936,18 @@ class CoreExport Module : public Extensible */ virtual void OnUserPostNick(User* user, const std::string &oldnick); - /** Called before an action which requires a channel privilage check. - * This function is called before many functions which check a users status on a channel, for example - * before opping a user, deopping a user, kicking a user, etc. - * There are several values for access_type which indicate for what reason access is being checked. - * These are:<br><br> - * AC_KICK - A user is being kicked<br> - * AC_DEOP - a user is being deopped<br> - * AC_OP - a user is being opped<br> - * AC_VOICE - a user is being voiced<br> - * AC_DEVOICE - a user is being devoiced<br> - * AC_HALFOP - a user is being halfopped<br> - * AC_DEHALFOP - a user is being dehalfopped<br> - * AC_INVITE - a user is being invited<br> - * AC_GENERAL_MODE - a user channel mode is being changed<br><br> - * Upon returning from your function you must return either ACR_DEFAULT, to indicate the module wishes - * to do nothing, or ACR_DENY where approprate to deny the action, and ACR_ALLOW where appropriate to allow - * the action. Please note that in the case of some access checks (such as AC_GENERAL_MODE) access may be - * denied 'upstream' causing other checks such as AC_DEOP to not be reached. Be very careful with use of the - * AC_GENERAL_MODE type, as it may inadvertently override the behaviour of other modules. When the access_type - * is AC_GENERAL_MODE, the destination of the mode will be NULL (as it has not yet been determined). - * @param source The source of the access check - * @param dest The destination of the access check - * @param channel The channel which is being checked - * @param access_type See above - */ - virtual ModResult OnAccessCheck(User* source,User* dest,Channel* channel,int access_type); + /** Called before any mode change, to allow a single access check for + * a full mode change (use OnRawMode to check individual modes) + * + * Returning MOD_RES_ALLOW will skip prefix level checks, but can be overridden by + * OnRawMode for each individual mode + * + * @param source the user making the mode change + * @param dest the user destination of the umode change (NULL if a channel mode) + * @param channel the channel destination of the mode change + * @param parameters raw mode parameters; parameters[0] is the user/channel being changed + */ + virtual ModResult OnPreMode(User* source, User* dest, Channel* channel, const std::vector<std::string>& parameters); /** Called when a 005 numeric is about to be output. * The module should modify the 005 numeric if needed to indicate its features. diff --git a/src/channels.cpp b/src/channels.cpp index 37edcebfb..adb0e6ebe 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -527,10 +527,8 @@ long Channel::KickUser(User *src, User *user, const char* reason) ModResult res; if (ServerInstance->ULine(src->server)) res = MOD_RES_ALLOW; - if (res == MOD_RES_PASSTHRU) + else FIRST_MOD_RESULT(ServerInstance, OnUserPreKick, res, (src,memb,reason)); - if (res == MOD_RES_PASSTHRU) - FIRST_MOD_RESULT(ServerInstance, OnAccessCheck, res, (src,user,this,AC_KICK)); if (res == MOD_RES_DENY) return this->GetUserCounter(); @@ -980,24 +978,27 @@ unsigned int Channel::GetPrefixValue(User* user) void Channel::SetPrefix(User* user, char prefix, unsigned int prefix_value, bool adding) { + ModeHandler* delta_mh = ServerInstance->Modes->FindMode(prefix, MODETYPE_CHANNEL); + if (!delta_mh) + return; UserMembIter m = userlist.find(user); - if (m != userlist.end()) + if (m == userlist.end()) + return; + for(unsigned int i=0; i < m->second->modes.length(); i++) { - for(unsigned int i=0; i < m->second->modes.length(); i++) + char mchar = m->second->modes[i]; + ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL); + if (mh && mh->GetPrefixRank() <= delta_mh->GetPrefixRank()) { - char mchar = m->second->modes[i]; - ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL); - if (mh && mh->GetPrefixRank() <= prefix_value) - { - m->second->modes = - m->second->modes.substr(0,i-1) + - (adding ? std::string(1, prefix) : "") + - m->second->modes.substr(mchar == prefix ? i+1 : i); - return; - } + m->second->modes = + m->second->modes.substr(0,i) + + (adding ? std::string(1, prefix) : "") + + m->second->modes.substr(mchar == prefix ? i+1 : i); + return; } - m->second->modes += std::string(1, prefix); } + if (adding) + m->second->modes += std::string(1, prefix); } void Channel::RemoveAllPrefixes(User* user) diff --git a/src/mode.cpp b/src/mode.cpp index c760df3f5..18384aaef 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -419,13 +419,8 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user, } else { - /* Overall access control hook for mode change */ - int hook = targetchannel ? AC_GENERAL_MODE : AC_GENERAL_UMODE; - - LastParse = mode_sequence; ModResult MOD_RESULT; - FIRST_MOD_RESULT(ServerInstance, OnAccessCheck, MOD_RESULT, (user, targetuser, targetchannel, hook)); - LastParse.clear(); + FIRST_MOD_RESULT(ServerInstance, OnPreMode, MOD_RESULT, (user, targetuser, targetchannel, parameters)); if (MOD_RESULT == MOD_RES_DENY) return; SkipAccessChecks = (MOD_RESULT == MOD_RES_ALLOW); diff --git a/src/modes/cmode_h.cpp b/src/modes/cmode_h.cpp index 480d69f0a..a61df4ba0 100644 --- a/src/modes/cmode_h.cpp +++ b/src/modes/cmode_h.cpp @@ -74,81 +74,5 @@ void ModeChannelHalfOp::RemoveMode(User*, irc::modestacker* stack) ModeAction ModeChannelHalfOp::OnModeChange(User* source, User*, Channel* channel, std::string ¶meter, bool adding) { - int status = channel->GetPrefixValue(source); - - /* Call the correct method depending on wether we're adding or removing the mode */ - if (adding) - { - parameter = this->AddHalfOp(source, parameter.c_str(), channel, status); - } - else - { - parameter = this->DelHalfOp(source, parameter.c_str(), channel, status); - } - /* If the method above 'ate' the parameter by reducing it to an empty string, then - * it won't matter wether we return ALLOW or DENY here, as an empty string overrides - * the return value and is always MODEACTION_DENY if the mode is supposed to have - * a parameter. - */ - if (parameter.length()) - return MODEACTION_ALLOW; - else - return MODEACTION_DENY; -} - -std::string ModeChannelHalfOp::AddHalfOp(User *user,const char* dest,Channel *chan,int status) -{ - User *d = ServerInstance->Modes->SanityChecks(user,dest,chan,status); - - if (d) - { - if (IS_LOCAL(user)) - { - ModResult MOD_RESULT; - FIRST_MOD_RESULT(ServerInstance, OnAccessCheck, MOD_RESULT, (user,d,chan,AC_HALFOP)); - - if (MOD_RESULT == MOD_RES_DENY) - return ""; - if (MOD_RESULT == MOD_RES_PASSTHRU) - { - if ((status < OP_VALUE) && (!ServerInstance->ULine(user->server))) - { - user->WriteServ("482 %s %s :You're not a channel operator",user->nick.c_str(), chan->name.c_str()); - return ""; - } - } - } - - return d->nick; - } - return ""; + return MODEACTION_ALLOW; } - -std::string ModeChannelHalfOp::DelHalfOp(User *user,const char *dest,Channel *chan,int status) -{ - User *d = ServerInstance->Modes->SanityChecks(user,dest,chan,status); - - if (d) - { - if (IS_LOCAL(user)) - { - ModResult MOD_RESULT; - FIRST_MOD_RESULT(ServerInstance, OnAccessCheck, MOD_RESULT, (user,d,chan,AC_DEHALFOP)); - - if (MOD_RESULT == MOD_RES_DENY) - return ""; - if (MOD_RESULT == MOD_RES_PASSTHRU) - { - if ((user != d) && ((status < OP_VALUE) && (!ServerInstance->ULine(user->server)))) - { - user->WriteServ("482 %s %s :You are not a channel operator",user->nick.c_str(), chan->name.c_str()); - return ""; - } - } - } - - return d->nick; - } - return ""; -} - diff --git a/src/modes/cmode_o.cpp b/src/modes/cmode_o.cpp index 9da9fa478..19c365ad9 100644 --- a/src/modes/cmode_o.cpp +++ b/src/modes/cmode_o.cpp @@ -72,80 +72,5 @@ void ModeChannelOp::RemoveMode(User*, irc::modestacker* stack) ModeAction ModeChannelOp::OnModeChange(User* source, User*, Channel* channel, std::string ¶meter, bool adding) { - int status = channel->GetPrefixValue(source); - - /* Call the correct method depending on wether we're adding or removing the mode */ - if (adding) - { - parameter = this->AddOp(source, parameter.c_str(), channel, status); - } - else - { - parameter = this->DelOp(source, parameter.c_str(), channel, status); - } - /* If the method above 'ate' the parameter by reducing it to an empty string, then - * it won't matter wether we return ALLOW or DENY here, as an empty string overrides - * the return value and is always MODEACTION_DENY if the mode is supposed to have - * a parameter. - */ - if (parameter.length()) - return MODEACTION_ALLOW; - else - return MODEACTION_DENY; -} - -std::string ModeChannelOp::AddOp(User *user,const char* dest,Channel *chan,int status) -{ - User *d = ServerInstance->Modes->SanityChecks(user,dest,chan,status); - - if (d) - { - if (IS_LOCAL(user)) - { - ModResult MOD_RESULT; - FIRST_MOD_RESULT(ServerInstance, OnAccessCheck, MOD_RESULT, (user,d,chan,AC_OP)); - - if (MOD_RESULT == MOD_RES_DENY) - return ""; - if (MOD_RESULT == MOD_RES_PASSTHRU) - { - if ((status < OP_VALUE) && (!ServerInstance->ULine(user->server))) - { - user->WriteServ("482 %s %s :You're not a channel operator",user->nick.c_str(), chan->name.c_str()); - return ""; - } - } - } - - return d->nick; - } - return ""; -} - -std::string ModeChannelOp::DelOp(User *user,const char *dest,Channel *chan,int status) -{ - User *d = ServerInstance->Modes->SanityChecks(user,dest,chan,status); - - if (d) - { - if (IS_LOCAL(user)) - { - ModResult MOD_RESULT; - FIRST_MOD_RESULT(ServerInstance, OnAccessCheck, MOD_RESULT, (user,d,chan,AC_DEOP)); - - if (MOD_RESULT == MOD_RES_DENY) - return ""; - if (MOD_RESULT == MOD_RES_PASSTHRU) - { - if ((status < OP_VALUE) && (!ServerInstance->ULine(user->server)) && (IS_LOCAL(user))) - { - user->WriteServ("482 %s %s :You are not a channel operator",user->nick.c_str(), chan->name.c_str()); - return ""; - } - } - } - - return d->nick; - } - return ""; + return MODEACTION_ALLOW; } diff --git a/src/modes/cmode_v.cpp b/src/modes/cmode_v.cpp index 031cefb7f..752dd509b 100644 --- a/src/modes/cmode_v.cpp +++ b/src/modes/cmode_v.cpp @@ -72,80 +72,5 @@ void ModeChannelVoice::RemoveMode(User*, irc::modestacker* stack) ModeAction ModeChannelVoice::OnModeChange(User* source, User*, Channel* channel, std::string ¶meter, bool adding) { - int status = channel->GetPrefixValue(source); - - /* Call the correct method depending on wether we're adding or removing the mode */ - if (adding) - { - parameter = this->AddVoice(source, parameter.c_str(), channel, status); - } - else - { - parameter = this->DelVoice(source, parameter.c_str(), channel, status); - } - /* If the method above 'ate' the parameter by reducing it to an empty string, then - * it won't matter wether we return ALLOW or DENY here, as an empty string overrides - * the return value and is always MODEACTION_DENY if the mode is supposed to have - * a parameter. - */ - if (parameter.length()) - return MODEACTION_ALLOW; - else - return MODEACTION_DENY; -} - -std::string ModeChannelVoice::AddVoice(User *user,const char* dest,Channel *chan,int status) -{ - User *d = ServerInstance->Modes->SanityChecks(user,dest,chan,status); - - if (d) - { - if (IS_LOCAL(user)) - { - ModResult MOD_RESULT; - FIRST_MOD_RESULT(ServerInstance, OnAccessCheck, MOD_RESULT, (user,d,chan,AC_VOICE)); - - if (MOD_RESULT == MOD_RES_DENY) - return ""; - if (MOD_RESULT == MOD_RES_PASSTHRU) - { - if ((status < HALFOP_VALUE) && (!ServerInstance->ULine(user->server))) - { - user->WriteServ("482 %s %s :You're not a channel (half)operator",user->nick.c_str(), chan->name.c_str()); - return ""; - } - } - } - - return d->nick; - } - return ""; -} - -std::string ModeChannelVoice::DelVoice(User *user,const char *dest,Channel *chan,int status) -{ - User *d = ServerInstance->Modes->SanityChecks(user,dest,chan,status); - - if (d) - { - if (IS_LOCAL(user)) - { - ModResult MOD_RESULT; - FIRST_MOD_RESULT(ServerInstance, OnAccessCheck, MOD_RESULT, (user,d,chan,AC_DEVOICE)); - - if (MOD_RESULT == MOD_RES_DENY) - return ""; - if (MOD_RESULT == MOD_RES_PASSTHRU) - { - if ((status < HALFOP_VALUE) && (!ServerInstance->ULine(user->server))) - { - user->WriteServ("482 %s %s :You are not a channel (half)operator",user->nick.c_str(), chan->name.c_str()); - return ""; - } - } - } - - return d->nick; - } - return ""; + return MODEACTION_ALLOW; } diff --git a/src/modules.cpp b/src/modules.cpp index 4a8a13a48..979c42119 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -129,7 +129,7 @@ ModResult Module::OnUserPreMessage(User*, void*, int, std::string&, char, CUList ModResult Module::OnUserPreNotice(User*, void*, int, std::string&, char, CUList&) { return MOD_RES_PASSTHRU; } ModResult Module::OnUserPreNick(User*, const std::string&) { return MOD_RES_PASSTHRU; } void Module::OnUserPostNick(User*, const std::string&) { } -ModResult Module::OnAccessCheck(User*, User*, Channel*, int) { return MOD_RES_PASSTHRU; } +ModResult Module::OnPreMode(User*, User*, Channel*, const std::vector<std::string>&) { return MOD_RES_PASSTHRU; } void Module::On005Numeric(std::string&) { } ModResult Module::OnKill(User*, User*, const std::string&) { return MOD_RES_PASSTHRU; } void Module::OnLoadModule(Module*, const std::string&) { } diff --git a/src/modules/m_chanprotect.cpp b/src/modules/m_chanprotect.cpp index 15481fb7f..1e03da617 100644 --- a/src/modules/m_chanprotect.cpp +++ b/src/modules/m_chanprotect.cpp @@ -256,7 +256,7 @@ class ChanProtect : public ModeHandler, public FounderProtectBase } } - virtual void DisplayList(User* user, Channel* channel) + void DisplayList(User* user, Channel* channel) { FounderProtectBase::DisplayList(user, channel); } @@ -296,8 +296,8 @@ class ModuleChanProtect : public Module throw ModuleException("Could not add new modes!"); } - Implementation eventlist[] = { I_OnUserKick, I_OnUserPart, I_OnUserPreJoin, I_OnAccessCheck }; - ServerInstance->Modules->Attach(eventlist, this, 4); + Implementation eventlist[] = { I_OnUserKick, I_OnUserPart, I_OnUserPreJoin }; + ServerInstance->Modules->Attach(eventlist, this, 3); } void LoadSettings() @@ -325,109 +325,18 @@ class ModuleChanProtect : public Module DeprivOthers = Conf.ReadFlag("chanprotect","deprotectothers", "yes", 0); } - virtual ModResult OnUserPreJoin(User *user, Channel *chan, const char *cname, std::string &privs, const std::string &keygiven) + ModResult OnUserPreJoin(User *user, Channel *chan, const char *cname, std::string &privs, const std::string &keygiven) { // if the user is the first user into the channel, mark them as the founder, but only if // the config option for it is set if (FirstInGetsFounder && !chan) - privs = std::string(1, QPrefix) + "@"; - - return MOD_RES_PASSTHRU; - } - - virtual ModResult OnAccessCheck(User* source,User* dest,Channel* channel,int access_type) - { - // here we perform access checks, this is the important bit that actually stops kicking/deopping - // etc of protected users. There are many types of access check, we're going to handle - // a relatively small number of them relevent to our module using a switch statement. - // don't allow action if: - // (A) Theyre founder (no matter what) - // (B) Theyre protected, unless you're founder or are protected and DeprivOthers is enabled - // always allow the action if: - // (A) The source is ulined - - if ((ServerInstance->ULine(source->nick.c_str())) || (ServerInstance->ULine(source->server)) || (!*source->server)) - return MOD_RES_PASSTHRU; - - if (!channel) - return MOD_RES_PASSTHRU; - - // Can do anything to yourself if deprotectself is enabled. - if (DeprivSelf && source == dest) - return MOD_RES_PASSTHRU; - - Membership* smemb = channel->GetUser(source); - Membership* dmemb = channel->GetUser(source); - bool candepriv_founder = (DeprivOthers && smemb && smemb->hasMode('q')); - bool candepriv_protect = smemb && (smemb->hasMode('q') || (DeprivOthers && smemb->hasMode('a'))); - bool desthas_founder = dmemb->hasMode('q'); - bool desthas_protect = dmemb->hasMode('a'); - - switch (access_type) - { - // a user has been deopped. Do we let them? hmmm... - case AC_DEOP: - if (desthas_founder && !candepriv_founder) - { - source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't deop "+dest->nick+" as they're a channel founder"); - return MOD_RES_DENY; - } - if (desthas_protect && !candepriv_protect) - { - source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't deop "+dest->nick+" as they're protected (+a)"); - return MOD_RES_DENY; - } - break; - - // a user is being kicked. do we chop off the end of the army boot? - case AC_KICK: - if (desthas_founder && !candepriv_founder) - { - source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't kick "+dest->nick+" as they're a channel founder"); - return MOD_RES_DENY; - } - if (desthas_protect && !candepriv_protect) - { - source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't kick "+dest->nick+" as they're protected (+a)"); - return MOD_RES_DENY; - } - break; - - // a user is being dehalfopped. Yes, we do disallow -h of a +ha user - case AC_DEHALFOP: - if (desthas_founder && !candepriv_founder) - { - source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't de-halfop "+dest->nick+" as they're a channel founder"); - return MOD_RES_DENY; - } - if (desthas_protect && !candepriv_protect) - { - source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't de-halfop "+dest->nick+" as they're protected (+a)"); - return MOD_RES_DENY; - } - break; - - // same with devoice. - case AC_DEVOICE: - if (desthas_founder && !candepriv_founder) - { - source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't devoice "+dest->nick+" as they're a channel founder"); - return MOD_RES_DENY; - } - if (desthas_protect && !candepriv_protect) - { - source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't devoice "+dest->nick+" as they're protected (+a)"); - return MOD_RES_DENY; - } - break; - } + privs += std::string(1, QPrefix); - // we dont know what this access check is, or dont care. just carry on, nothing to see here. return MOD_RES_PASSTHRU; } - virtual ~ModuleChanProtect() + ~ModuleChanProtect() { ServerInstance->Modes->DelMode(cp); ServerInstance->Modes->DelMode(cf); @@ -435,7 +344,7 @@ class ModuleChanProtect : public Module delete cf; } - virtual Version GetVersion() + Version GetVersion() { return Version("Founder and Protect modes (+qa)", VF_COMMON | VF_VENDOR); } diff --git a/src/modules/m_nokicks.cpp b/src/modules/m_nokicks.cpp index 4af76e0d8..1324a7c03 100644 --- a/src/modules/m_nokicks.cpp +++ b/src/modules/m_nokicks.cpp @@ -31,43 +31,40 @@ class ModuleNoKicks : public Module { if (!ServerInstance->Modes->AddMode(&nk)) throw ModuleException("Could not add new modes!"); - Implementation eventlist[] = { I_OnAccessCheck, I_On005Numeric }; + Implementation eventlist[] = { I_OnUserPreKick, I_On005Numeric }; ServerInstance->Modules->Attach(eventlist, this, 2); } - virtual void On005Numeric(std::string &output) + void On005Numeric(std::string &output) { ServerInstance->AddExtBanChar('Q'); } - virtual ModResult OnAccessCheck(User* source,User* dest,Channel* channel,int access_type) + ModResult OnUserPreKick(User* source, Membership* memb, const std::string &reason) { - if (access_type == AC_KICK) + if (!memb->chan->GetExtBanStatus(source, 'Q').check(!memb->chan->IsModeSet('Q'))) { - if (!channel->GetExtBanStatus(source, 'Q').check(!channel->IsModeSet('Q'))) + if ((ServerInstance->ULine(source->nick.c_str())) || (ServerInstance->ULine(source->server)) || (!*source->server)) { - if ((ServerInstance->ULine(source->nick.c_str())) || (ServerInstance->ULine(source->server)) || (!*source->server)) - { - // ulines can still kick with +Q in place - return MOD_RES_PASSTHRU; - } - else - { - // nobody else can (not even opers with override, and founders) - source->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :Can't kick user %s from channel (+Q set)",source->nick.c_str(), channel->name.c_str(), dest->nick.c_str()); - return MOD_RES_DENY; - } + // ulines can still kick with +Q in place + return MOD_RES_PASSTHRU; + } + else + { + // nobody else can (not even opers with override, and founders) + source->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :Can't kick user %s from channel (+Q set)",source->nick.c_str(), memb->chan->name.c_str(), memb->user->nick.c_str()); + return MOD_RES_DENY; } } return MOD_RES_PASSTHRU; } - virtual ~ModuleNoKicks() + ~ModuleNoKicks() { ServerInstance->Modes->DelMode(&nk); } - virtual Version GetVersion() + Version GetVersion() { return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION); } diff --git a/src/modules/m_ojoin.cpp b/src/modules/m_ojoin.cpp index c03f2ad1f..8c45c0d50 100644 --- a/src/modules/m_ojoin.cpp +++ b/src/modules/m_ojoin.cpp @@ -259,7 +259,7 @@ class ModuleOjoin : public Module ServerInstance->AddCommand(&mycommand); - Implementation eventlist[] = { I_OnUserPreJoin, I_OnUserKick, I_OnUserPart, I_OnAccessCheck, I_OnRehash }; + Implementation eventlist[] = { I_OnUserPreJoin, I_OnUserKick, I_OnUserPart, I_OnUserPreKick, I_OnRehash }; ServerInstance->Modules->Attach(eventlist, this, 5); } @@ -294,59 +294,21 @@ class ModuleOjoin : public Module op = Conf.ReadFlag("ojoin", "op", "yes", 0); } - ModResult OnAccessCheck(User* source,User* dest,Channel* channel,int access_type) + ModResult OnUserPreKick(User* source, Membership* memb, const std::string &reason) { - // Here's where we preform access checks, and disallow any kicking/deopping - // of +Y users. - - // If there's no dest, it's not for us. - if (!dest || !channel) - return MOD_RES_PASSTHRU; - - // If a ulined nickname, or a server is setting the mode, let it - // do whatever it wants. if ((ServerInstance->ULine(source->nick.c_str())) || (ServerInstance->ULine(source->server)) || (!*source->server)) return MOD_RES_PASSTHRU; - Membership* m = channel->GetUser(dest); - // Don't do anything if they're not +Y - if (!m || !m->hasMode('Y')) + if (!memb->hasMode('Y')) return MOD_RES_PASSTHRU; // Let them do whatever they want to themselves. - if (source == dest) + if (source == memb->user) return MOD_RES_PASSTHRU; - switch (access_type) - { - // Disallow deopping of +Y users. - case AC_DEOP: - source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't deop "+dest->nick+" as they're on official network business."); - return MOD_RES_DENY; - break; - - // Kicking people who are here on network business is a no no. - case AC_KICK: - source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't kick "+dest->nick+" as they're on official network business."); - return MOD_RES_DENY; - break; - - // Yes, they're immune to dehalfopping too. - case AC_DEHALFOP: - source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't de-halfop "+dest->nick+" as they're on official network business."); - return MOD_RES_DENY; - break; - - // same with devoice. - case AC_DEVOICE: - source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't devoice "+dest->nick+" as they're on official network business."); - return MOD_RES_DENY; - break; - } - - // Some other access check that doesn't fall into the above. Let it through. - return MOD_RES_PASSTHRU; + source->WriteNumeric(484, source->nick+" "+memb->chan->name+" :Can't kick "+memb->user->nick+" as they're on official network business."); + return MOD_RES_DENY; } ~ModuleOjoin() diff --git a/src/modules/m_override.cpp b/src/modules/m_override.cpp index 38864f400..1f2eb876a 100644 --- a/src/modules/m_override.cpp +++ b/src/modules/m_override.cpp @@ -23,9 +23,6 @@ class ModuleOverride : public Module override_t overrides; bool RequireKey; bool NoisyOverride; - bool OverriddenMode; - bool OverOther; - int OverOps, OverDeops, OverVoices, OverDevoices, OverHalfops, OverDehalfops; public: @@ -39,13 +36,11 @@ class ModuleOverride : public Module { throw ModuleException("m_override: Unable to publish feature 'Override'"); } - OverriddenMode = OverOther = false; - OverOps = OverDeops = OverVoices = OverDevoices = OverHalfops = OverDehalfops = 0; - Implementation eventlist[] = { I_OnRehash, I_OnAccessCheck, I_On005Numeric, I_OnUserPreJoin, I_OnUserPreKick, I_OnPostCommand, I_OnPreTopicChange, I_OnRequest }; - ServerInstance->Modules->Attach(eventlist, this, 8); + Implementation eventlist[] = { I_OnRehash, I_OnPreMode, I_On005Numeric, I_OnUserPreJoin, I_OnUserPreKick, I_OnPreTopicChange, I_OnRequest }; + ServerInstance->Modules->Attach(eventlist, this, 7); } - virtual void OnRehash(User* user) + void OnRehash(User* user) { // on a rehash we delete our classes for good measure and create them again. ConfigReader Conf(ServerInstance); @@ -64,43 +59,12 @@ class ModuleOverride : public Module } } - - virtual void OnPostCommand(const std::string &command, const std::vector<std::string> ¶meters, User *user, CmdResult result, const std::string &original_line) - { - if (OverriddenMode) - { - if ((irc::string(command.c_str()) == "MODE") && (result == CMD_SUCCESS) && !ServerInstance->Modes->GetLastParse().empty()) - { - std::string msg = std::string(user->nick)+" overriding modes: "+ServerInstance->Modes->GetLastParse()+" [Detail: "; - if (OverOps) - msg += ConvToStr(OverOps)+" op"+(OverOps != 1 ? "s" : "")+", "; - if (OverDeops) - msg += ConvToStr(OverDeops)+" deop"+(OverDeops != 1 ? "s" : "")+", "; - if (OverVoices) - msg += ConvToStr(OverVoices)+" voice"+(OverVoices != 1 ? "s" : "")+", "; - if (OverDevoices) - msg += ConvToStr(OverDevoices)+" devoice"+(OverDevoices != 1 ? "s" : "")+", "; - if (OverHalfops) - msg += ConvToStr(OverHalfops)+" halfop"+(OverHalfops != 1 ? "s" : "")+", "; - if (OverDehalfops) - msg += ConvToStr(OverDehalfops)+" dehalfop"+(OverDehalfops != 1 ? "s" : "")+", "; - if (OverOther) - msg += "others, "; - msg.replace(msg.length()-2, 2, 1, ']'); - ServerInstance->SNO->WriteGlobalSno('G',msg); - } - - OverriddenMode = OverOther = false; - OverOps = OverDeops = OverVoices = OverDevoices = OverHalfops = OverDehalfops = 0; - } - } - - virtual void On005Numeric(std::string &output) + void On005Numeric(std::string &output) { output.append(" OVERRIDE"); } - virtual bool CanOverride(User* source, const char* token) + bool CanOverride(User* source, const char* token) { // checks to see if the oper's type has <type:override> override_t::iterator j = overrides.find(source->oper); @@ -116,7 +80,7 @@ class ModuleOverride : public Module } - virtual ModResult OnPreTopicChange(User *source, Channel *channel, const std::string &topic) + ModResult OnPreTopicChange(User *source, Channel *channel, const std::string &topic) { if (IS_LOCAL(source) && IS_OPER(source) && CanOverride(source, "TOPIC")) { @@ -146,89 +110,29 @@ class ModuleOverride : public Module return MOD_RES_PASSTHRU; } - virtual ModResult OnAccessCheck(User* source,User* dest,Channel* channel,int access_type) + ModResult OnPreMode(User* source,User* dest,Channel* channel, const std::vector<std::string>& parameters) { if (!IS_OPER(source)) return MOD_RES_PASSTHRU; if (!source || !channel) return MOD_RES_PASSTHRU; - int mode = 0; + unsigned int mode = 0; if (channel->HasUser(source)) mode = channel->GetPrefixValue(source); - bool over_this = false; - switch (access_type) + if (mode < HALFOP_VALUE && CanOverride(source, "MODE")) { - case AC_DEOP: - if (mode < OP_VALUE && CanOverride(source,"MODEDEOP")) - { - over_this = true; - OverDeops++; - } - break; - case AC_OP: - if (mode < OP_VALUE && CanOverride(source,"MODEOP")) - { - over_this = true; - OverOps++; - } - break; - case AC_VOICE: - if (mode < HALFOP_VALUE && CanOverride(source,"MODEVOICE")) - { - over_this = true; - OverVoices++; - } - break; - case AC_DEVOICE: - if (mode < HALFOP_VALUE && CanOverride(source,"MODEDEVOICE")) - { - over_this = true; - OverDevoices++; - } - break; - case AC_HALFOP: - if (mode < OP_VALUE && CanOverride(source,"MODEHALFOP")) - { - over_this = true; - OverHalfops++; - } - break; - case AC_DEHALFOP: - if (mode < OP_VALUE && CanOverride(source,"MODEDEHALFOP")) - { - over_this = true; - OverDehalfops++; - } - break; - case AC_GENERAL_MODE: - { - std::string modes = ServerInstance->Modes->GetLastParse(); - bool ohv_only = (modes.find_first_not_of("+-ohv") == std::string::npos); - - if (mode < HALFOP_VALUE && (ohv_only || CanOverride(source,"OTHERMODE"))) - { - over_this = true; - if (!ohv_only) - OverOther = true; - } - } - break; - } - - if (over_this) - { - OverriddenMode = true; + std::string msg = std::string(source->nick)+" overriding modes:"; + for(unsigned int i=0; i < parameters.size(); i++) + msg += " " + parameters[i]; + ServerInstance->SNO->WriteGlobalSno('G',msg); return MOD_RES_ALLOW; } - else - { - return MOD_RES_PASSTHRU; - } + return MOD_RES_PASSTHRU; } - virtual ModResult OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs, const std::string &keygiven) + ModResult OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs, const std::string &keygiven) { if (IS_LOCAL(user) && IS_OPER(user)) { @@ -302,7 +206,7 @@ class ModuleOverride : public Module return MOD_RES_PASSTHRU; } - virtual const char* OnRequest(Request* request) + const char* OnRequest(Request* request) { if(strcmp(OVRREQID, request->GetId()) == 0) { @@ -312,13 +216,13 @@ class ModuleOverride : public Module return NULL; } - virtual ~ModuleOverride() + ~ModuleOverride() { ServerInstance->Modules->UnpublishFeature("Override"); ServerInstance->SNO->DisableSnomask('G'); } - virtual Version GetVersion() + Version GetVersion() { return Version("$Id$",VF_VENDOR,API_VERSION); } diff --git a/src/modules/m_samode.cpp b/src/modules/m_samode.cpp index e0e751e7b..2a185680d 100644 --- a/src/modules/m_samode.cpp +++ b/src/modules/m_samode.cpp @@ -46,19 +46,19 @@ class ModuleSaMode : public Module : Module(Me), cmd(Me, this) { ServerInstance->AddCommand(&cmd); - ServerInstance->Modules->Attach(I_OnAccessCheck, this); + ServerInstance->Modules->Attach(I_OnPreMode, this); } - virtual ~ModuleSaMode() + ~ModuleSaMode() { } - virtual Version GetVersion() + Version GetVersion() { return Version("$Id$", VF_VENDOR, API_VERSION); } - virtual ModResult OnAccessCheck(User* source,User* dest,Channel* channel,int access_type) + ModResult OnPreMode(User* source,User* dest,Channel* channel, const std::vector<std::string>& parameters) { if (cmd.active) return MOD_RES_ALLOW; @@ -68,7 +68,7 @@ class ModuleSaMode : public Module void Prioritize() { Module *override = ServerInstance->Modules->Find("m_override.so"); - ServerInstance->Modules->SetPriority(this, I_OnAccessCheck, PRIORITY_BEFORE, &override); + ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_BEFORE, &override); } }; |