X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_override.cpp;h=116042ae62f31958ceeae1857de6277a28cffc3b;hb=6ab1d0dffb8084bf6a2ad8a446a3836fa3760c8a;hp=ae90a76a7d04bf17080c474dd6ceaea44cc3a43e;hpb=7b3f2150387d9e5d9468ad2eaaacef0acc08564d;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_override.cpp b/src/modules/m_override.cpp index ae90a76a7..116042ae6 100644 --- a/src/modules/m_override.cpp +++ b/src/modules/m_override.cpp @@ -1,75 +1,195 @@ -#include +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev. + * E-mail: + * + * + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ #include "users.h" #include "channels.h" #include "modules.h" +#include "helperfuncs.h" -/* $ModDesc: Provides channel modes +a and +q */ +/* $ModDesc: Provides support for unreal-style oper-override */ -char dummyvalue[] = "on"; +typedef std::map override_t; class ModuleOverride : public Module { Server *Srv; + override_t overrides; bool NoisyOverride; - ConfigReader *Conf; - public: - ModuleOverride() + ModuleOverride(Server* Me) + : Module::Module(Me) { // here we initialise our module. Use new to create new instances of the required // classes. - Srv = new Server; - Conf = new ConfigReader; + Srv = Me; // read our config options (main config file) - NoisyOverride = Conf->ReadFlag("override","noisy",0); + OnRehash(""); } - virtual void OnRehash() + virtual void OnRehash(const std::string ¶meter) { // on a rehash we delete our classes for good measure and create them again. - delete Conf; - Conf = new ConfigReader; + ConfigReader* Conf = new ConfigReader; + // re-read our config options on a rehash NoisyOverride = Conf->ReadFlag("override","noisy",0); + overrides.clear(); + for (int j =0; j < Conf->Enumerate("type"); j++) + { + std::string typen = Conf->ReadValue("type","name",j); + std::string tokenlist = Conf->ReadValue("type","override",j); + overrides[typen] = tokenlist; + } + + DELETE(Conf); + } + + void Implements(char* List) + { + List[I_OnRehash] = List[I_OnAccessCheck] = List[I_On005Numeric] = List[I_OnUserPreJoin] = List[I_OnUserPreKick] = 1; + } + + virtual void On005Numeric(std::string &output) + { + output.append(" OVERRIDE"); + } + + virtual bool CanOverride(userrec* source, char* token) + { + // checks to see if the oper's type has + override_t::iterator j = overrides.find(source->oper); + + if (j != overrides.end()) + { + // its defined, return its value as a boolean for if the token is set + return (j->second.find(token, 0) != std::string::npos); + } + + // its not defined at all, count as false + return false; + } + + virtual int OnUserPreKick(userrec* source, userrec* user, chanrec* chan, const std::string &reason) + { + if ((*source->oper) && (CanOverride(source,"KICK"))) + { + if (((Srv->ChanMode(source,chan) == "%") && (Srv->ChanMode(user,chan) == "@")) || (Srv->ChanMode(source,chan) == "")) + { + Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Kicked "+std::string(user->nick)+" on "+std::string(chan->name)+" ("+reason+")"); + } + /* Returning -1 explicitly allows the kick */ + return -1; + } + return 0; } virtual int OnAccessCheck(userrec* source,userrec* dest,chanrec* channel,int access_type) { - if (strchr(source->modes,'o')) + if (*source->oper) { - if ((Srv->ChanMode(source,channel) != "%") && (Srv->ChanMode(source,channel) != "@")) + if ((Srv) && (source) && (channel)) { - switch (access_type) + // Fix by brain - allow the change if they arent on channel - rely on boolean short-circuit + // to not check the other items in the statement if they arent on the channel + std::string mode = Srv->ChanMode(source,channel); + if ((!channel->HasUser(source)) || ((mode != "%") && (mode != "@"))) { - case AC_KICK: - Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Kicked "+std::string(dest->nick)+" on "+std::string(channel->name)); - break; - case AC_DEOP: - Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Deopped "+std::string(dest->nick)+" on "+std::string(channel->name)); - break; - case AC_OP: - Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Opped "+std::string(dest->nick)+" on "+std::string(channel->name)); - break; - case AC_VOICE: - Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Voiced "+std::string(dest->nick)+" on "+std::string(channel->name)); - break; - case AC_DEVOICE: - Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Devoiced "+std::string(dest->nick)+" on "+std::string(channel->name)); - break; - case AC_HALFOP: - Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Halfopped "+std::string(dest->nick)+" on "+std::string(channel->name)); - break; - case AC_DEHALFOP: - Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Dehalfopped "+std::string(dest->nick)+" on "+std::string(channel->name)); - break; + switch (access_type) + { + case AC_DEOP: + if (CanOverride(source,"MODEDEOP")) + { + Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Deopped "+std::string(dest->nick)+" on "+std::string(channel->name)); + return ACR_ALLOW; + } + else + { + return ACR_DEFAULT; + } + + case AC_OP: + if (CanOverride(source,"MODEOP")) + { + Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Opped "+std::string(dest->nick)+" on "+std::string(channel->name)); + return ACR_ALLOW; + } + else + { + return ACR_DEFAULT; + } + + case AC_VOICE: + if (CanOverride(source,"MODEVOICE")) + { + Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Voiced "+std::string(dest->nick)+" on "+std::string(channel->name)); + return ACR_ALLOW; + } + else + { + return ACR_DEFAULT; + } + + case AC_DEVOICE: + if (CanOverride(source,"MODEDEVOICE")) + { + Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Devoiced "+std::string(dest->nick)+" on "+std::string(channel->name)); + return ACR_ALLOW; + } + else + { + return ACR_DEFAULT; + } + + case AC_HALFOP: + if (CanOverride(source,"MODEHALFOP")) + { + Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Halfopped "+std::string(dest->nick)+" on "+std::string(channel->name)); + return ACR_ALLOW; + } + else + { + return ACR_DEFAULT; + } + + case AC_DEHALFOP: + if (CanOverride(source,"MODEDEHALFOP")) + { + Srv->SendOpers("*** NOTICE: "+std::string(source->nick)+" Override-Dehalfopped "+std::string(dest->nick)+" on "+std::string(channel->name)); + return ACR_ALLOW; + } + else + { + return ACR_DEFAULT; + } + } } } - return ACR_ALLOW; + + if (CanOverride(source,"OTHERMODE")) + { + return ACR_ALLOW; + } + else + { + return ACR_DEFAULT; + } } return ACR_DEFAULT; @@ -77,22 +197,46 @@ class ModuleOverride : public Module virtual int OnUserPreJoin(userrec* user, chanrec* chan, const char* cname) { - if (strchr(user->modes,'o')) + if (*user->oper) { if (chan) { - if ((chan->inviteonly) || (chan->key[0]) || (chan->limit >= Srv->CountUsers(chan))) + if ((chan->modes[CM_INVITEONLY]) && (CanOverride(user,"INVITE"))) { if (NoisyOverride) { - if (!user->IsInvited(chan->name)) + irc::string x = chan->name; + if (!user->IsInvited(x)) { - WriteChannelWithServ((char*)Srv->GetServerName().c_str(),chan,user,"NOTICE %s :%s invited himself into the channel",cname,user->nick); + /* XXX - Ugly cast for a parameter that isn't used? :< - Om */ + chan->WriteChannelWithServ(Srv->GetServerName().c_str(), "NOTICE %s :%s invited himself into the channel", cname, user->nick); } } - Srv->SendOpers("*** "+std::string(user->nick)+" used operoverride to bypass +i, +k or +l on "+std::string(cname)); + Srv->SendOpers("*** "+std::string(user->nick)+" used operoverride to bypass +i on "+std::string(cname)); + return -1; + } + + if ((chan->key[0]) && (CanOverride(user,"KEY"))) + { + if (NoisyOverride) + chan->WriteChannelWithServ(Srv->GetServerName().c_str(), "NOTICE %s :%s bypassed the channel key", cname, user->nick); + Srv->SendOpers("*** "+std::string(user->nick)+" used operoverride to bypass +k on "+std::string(cname)); + return -1; + } + + if ((chan->limit > 0) && (Srv->CountUsers(chan) >= chan->limit) && (CanOverride(user,"LIMIT"))) + { + if (NoisyOverride) + chan->WriteChannelWithServ(Srv->GetServerName().c_str(), "NOTICE %s :%s passed through your channel limit", cname, user->nick); + Srv->SendOpers("*** "+std::string(user->nick)+" used operoverride to bypass +l on "+std::string(cname)); + return -1; + } + + if (CanOverride(user,"BANWALK")) + { + // other join + return -1; } - return -1; } } return 0; @@ -100,13 +244,11 @@ class ModuleOverride : public Module virtual ~ModuleOverride() { - delete Conf; - delete Srv; } virtual Version GetVersion() { - return Version(1,0,0,0); + return Version(1,0,0,1,VF_VENDOR); } }; @@ -122,9 +264,9 @@ class ModuleOverrideFactory : public ModuleFactory { } - virtual Module * CreateModule() + virtual Module * CreateModule(Server* Me) { - return new ModuleOverride; + return new ModuleOverride(Me); } }; @@ -134,4 +276,3 @@ extern "C" void * init_module( void ) { return new ModuleOverrideFactory; } -