1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * InspIRCd: (C) 2002-2007 InspIRCd Development Team
6 * See: http://www.inspircd.org/wiki/index.php/Credits
8 * This program is free but copyrighted software; see
9 * the file COPYING for details.
11 * ---------------------------------------------------
17 /* $ModDesc: Provides support for unreal-style oper-override */
19 typedef std::map<std::string,std::string> override_t;
21 class ModuleOverride : public Module
27 int OverOps, OverDeops, OverVoices, OverDevoices, OverHalfops, OverDehalfops;
31 ModuleOverride(InspIRCd* Me)
34 // read our config options (main config file)
36 ServerInstance->SNO->EnableSnomask('O',"OVERRIDE");
37 OverriddenMode = false;
38 OverOps = OverDeops = OverVoices = OverDevoices = OverHalfops = OverDehalfops = 0;
41 virtual void OnRehash(userrec* user, const std::string ¶meter)
43 // on a rehash we delete our classes for good measure and create them again.
44 ConfigReader* Conf = new ConfigReader(ServerInstance);
46 // re-read our config options on a rehash
47 NoisyOverride = Conf->ReadFlag("override","noisy",0);
49 for (int j =0; j < Conf->Enumerate("type"); j++)
51 std::string typen = Conf->ReadValue("type","name",j);
52 std::string tokenlist = Conf->ReadValue("type","override",j);
53 overrides[typen] = tokenlist;
59 void Implements(char* List)
61 List[I_OnRehash] = List[I_OnAccessCheck] = List[I_On005Numeric] = List[I_OnUserPreJoin] = List[I_OnUserPreKick] = List[I_OnPostCommand] = 1;
64 virtual void OnPostCommand(const std::string &command, const char** parameters, int pcnt, userrec *user, CmdResult result, const std::string &original_line)
66 if ((NoisyOverride) && (OverriddenMode) && (irc::string(command.c_str()) == "MODE") && (result == CMD_SUCCESS))
68 int Total = OverOps + OverDeops + OverVoices + OverDevoices + OverHalfops + OverDehalfops;
70 ServerInstance->SNO->WriteToSnoMask('O',std::string(user->nick)+" Overriding modes: "+ServerInstance->Modes->GetLastParse()+" "+(Total ? "[Detail: " : "")+
71 (OverOps ? ConvToStr(OverOps)+" op"+(OverOps != 1 ? "s" : "")+" " : "")+
72 (OverDeops ? ConvToStr(OverDeops)+" deop"+(OverDeops != 1 ? "s" : "")+" " : "")+
73 (OverVoices ? ConvToStr(OverVoices)+" voice"+(OverVoices != 1 ? "s" : "")+" " : "")+
74 (OverDevoices ? ConvToStr(OverDevoices)+" devoice"+(OverDevoices != 1 ? "s" : "")+" " : "")+
75 (OverHalfops ? ConvToStr(OverHalfops)+" halfop"+(OverHalfops != 1 ? "s" : "")+" " : "")+
76 (OverDehalfops ? ConvToStr(OverDehalfops)+" dehalfop"+(OverDehalfops != 1 ? "s" : "") : "")
79 OverriddenMode = false;
80 OverOps = OverDeops = OverVoices = OverDevoices = OverHalfops = OverDehalfops = 0;
84 virtual void On005Numeric(std::string &output)
86 output.append(" OVERRIDE");
89 virtual bool CanOverride(userrec* source, const char* token)
91 // checks to see if the oper's type has <type:override>
92 override_t::iterator j = overrides.find(source->oper);
94 if (j != overrides.end())
96 // its defined or * is set, return its value as a boolean for if the token is set
97 return ((j->second.find(token, 0) != std::string::npos) || (j->second.find("*", 0) != std::string::npos));
100 // its not defined at all, count as false
104 virtual int OnUserPreKick(userrec* source, userrec* user, chanrec* chan, const std::string &reason)
106 if (IS_OPER(source) && CanOverride(source,"KICK"))
108 if (((chan->GetStatus(source) == STATUS_HOP) && (chan->GetStatus(user) == STATUS_OP)) || (chan->GetStatus(source) < STATUS_VOICE))
110 ServerInstance->SNO->WriteToSnoMask('O',std::string(source->nick)+" Override-Kicked "+std::string(user->nick)+" on "+std::string(chan->name)+" ("+reason+")");
112 /* Returning -1 explicitly allows the kick */
118 virtual int OnAccessCheck(userrec* source,userrec* dest,chanrec* channel,int access_type)
122 if (source && channel)
124 // Fix by brain - allow the change if they arent on channel - rely on boolean short-circuit
125 // to not check the other items in the statement if they arent on the channel
126 int mode = channel->GetStatus(source);
130 if (CanOverride(source,"MODEDEOP"))
133 if ((!channel->HasUser(source)) || (mode < STATUS_OP))
143 if (CanOverride(source,"MODEOP"))
146 if ((!channel->HasUser(source)) || (mode < STATUS_OP))
156 if (CanOverride(source,"MODEVOICE"))
159 if ((!channel->HasUser(source)) || (mode < STATUS_HOP))
169 if (CanOverride(source,"MODEDEVOICE"))
172 if ((!channel->HasUser(source)) || (mode < STATUS_HOP))
182 if (CanOverride(source,"MODEHALFOP"))
185 if ((!channel->HasUser(source)) || (mode < STATUS_OP))
195 if (CanOverride(source,"MODEDEHALFOP"))
198 if ((!channel->HasUser(source)) || (mode < STATUS_OP))
209 if (CanOverride(source,"OTHERMODE"))
212 if ((!channel->HasUser(source)) || (mode < STATUS_OP))
214 OverriddenMode = true;
215 OverOps = OverDeops = OverVoices = OverDevoices = OverHalfops = OverDehalfops = 0;
229 virtual int OnUserPreJoin(userrec* user, chanrec* chan, const char* cname, std::string &privs)
235 if ((chan->modes[CM_INVITEONLY]) && (CanOverride(user,"INVITE")))
237 irc::string x = chan->name;
238 if (!user->IsInvited(x))
240 /* XXX - Ugly cast for a parameter that isn't used? :< - Om */
242 chan->WriteChannelWithServ(ServerInstance->Config->ServerName, "NOTICE %s :%s used oper-override to bypass invite-only", cname, user->nick);
243 ServerInstance->SNO->WriteToSnoMask('O',std::string(user->nick)+" used operoverride to bypass +i on "+std::string(cname));
248 if ((*chan->key) && (CanOverride(user,"KEY")))
251 chan->WriteChannelWithServ(ServerInstance->Config->ServerName, "NOTICE %s :%s used oper-override to bypass the channel key", cname, user->nick);
252 ServerInstance->SNO->WriteToSnoMask('O',std::string(user->nick)+" used operoverride to bypass +k on "+std::string(cname));
256 if ((chan->limit > 0) && (chan->GetUserCounter() >= chan->limit) && (CanOverride(user,"LIMIT")))
259 chan->WriteChannelWithServ(ServerInstance->Config->ServerName, "NOTICE %s :%s used oper-override to bypass the channel limit", cname, user->nick);
260 ServerInstance->SNO->WriteToSnoMask('O',std::string(user->nick)+" used operoverride to bypass +l on "+std::string(cname));
264 if (CanOverride(user,"BANWALK"))
266 if (chan->IsBanned(user))
269 chan->WriteChannelWithServ(ServerInstance->Config->ServerName, "NOTICE %s :%s used oper-override to bypass channel ban", cname, user->nick);
270 ServerInstance->SNO->WriteToSnoMask('O',"%s used oper-override to bypass channel ban on %s", user->nick, cname);
279 virtual ~ModuleOverride()
281 ServerInstance->SNO->DisableSnomask('O');
284 virtual Version GetVersion()
286 return Version(1,1,0,1,VF_VENDOR,API_VERSION);
290 MODULE_INIT(ModuleOverride)