summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/operserv.example.conf6
-rw-r--r--include/config.h2
-rw-r--r--include/oper.h61
-rw-r--r--modules/commands/os_akill.cpp28
-rw-r--r--modules/commands/os_chankill.cpp3
-rw-r--r--modules/commands/os_defcon.cpp29
-rw-r--r--modules/commands/os_session.cpp4
-rw-r--r--modules/commands/os_sxline.cpp90
-rw-r--r--modules/database/db_old.cpp24
-rw-r--r--modules/database/db_plain.cpp6
-rw-r--r--modules/extra/m_dnsbl.cpp11
-rw-r--r--modules/extra/m_proxyscan.cpp13
-rw-r--r--modules/pseudoclients/operserv.cpp143
-rw-r--r--src/config.cpp1
-rw-r--r--src/operserv.cpp121
15 files changed, 274 insertions, 268 deletions
diff --git a/data/operserv.example.conf b/data/operserv.example.conf
index 69467516c..ac038a58a 100644
--- a/data/operserv.example.conf
+++ b/data/operserv.example.conf
@@ -205,6 +205,12 @@ operserv
addakiller = yes
/*
+ * Adds akill IDs to akills. Akill IDs are given to users in their ban reason and can be used to easily view,
+ * modify, or remove an akill from the ID.
+ */
+ akillids = yes
+
+ /*
* If set, only IRC Operators will be permitted to use OperServ, regardless of module-based command
* access restrictions.
*
diff --git a/include/config.h b/include/config.h
index e333a06fd..51fcfc424 100644
--- a/include/config.h
+++ b/include/config.h
@@ -611,6 +611,8 @@ class CoreExport ServerConfig
bool WallExceptionExpire;
/* Add the akillers nick to the akill reason */
bool AddAkiller;
+ /* Add akill ids to akill reason */
+ bool AkillIds;
/* Limit sessions */
bool LimitSessions;
diff --git a/include/oper.h b/include/oper.h
index fb046bdbe..1d4092b4a 100644
--- a/include/oper.h
+++ b/include/oper.h
@@ -21,11 +21,12 @@ class CoreExport XLine : public Serializable<XLine>
time_t Created;
time_t Expires;
Anope::string Reason;
- Anope::string Manager;
+ XLineManager *manager;
+ Anope::string UID;
- XLine(const Anope::string &mask, const Anope::string &reason = "");
+ XLine(const Anope::string &mask, const Anope::string &reason = "", const Anope::string &uid = "");
- XLine(const Anope::string &mask, const Anope::string &by, const time_t expires, const Anope::string &reason);
+ XLine(const Anope::string &mask, const Anope::string &by, const time_t expires, const Anope::string &reason, const Anope::string &uid);
Anope::string GetNick() const;
Anope::string GetUser() const;
@@ -39,26 +40,13 @@ class CoreExport XLine : public Serializable<XLine>
class CoreExport XLineManager : public Service<XLineManager>
{
char type;
- protected:
/* List of XLines in this XLineManager */
std::vector<XLine *> XLines;
+ static std::map<Anope::string, XLine *, std::less<ci::string> > XLinesByUID;
public:
/* List of XLine managers we check users against in XLineManager::CheckAll */
static std::list<XLineManager *> XLineManagers;
- /** Constructor
- */
- XLineManager(Module *creator, const Anope::string &name, char t);
-
- /** Destructor
- */
- virtual ~XLineManager();
-
- /** The type of xline provided by this service
- * @return The type
- */
- const char &Type();
-
/** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll
* It is important XLineManagers are registered in the proper order. Eg, if you had one akilling
* clients and one handing them free olines, you would want the akilling one first. This way if a client
@@ -78,6 +66,24 @@ class CoreExport XLineManager : public Service<XLineManager>
*/
static std::pair<XLineManager *, XLine *> CheckAll(User *u);
+ /** Generate a unique ID for this XLine
+ * @return A unique ID
+ */
+ static Anope::string GenerateUID();
+
+ /** Constructor
+ */
+ XLineManager(Module *creator, const Anope::string &name, char t);
+
+ /** Destructor
+ */
+ virtual ~XLineManager();
+
+ /** The type of xline provided by this service
+ * @return The type
+ */
+ const char &Type();
+
/** Get the number of XLines in this XLineManager
* @return The number of XLines
*/
@@ -109,22 +115,6 @@ class CoreExport XLineManager : public Service<XLineManager>
*/
void Clear();
- /** Add an entry to this XLine Manager
- * @param mask The mask of the XLine
- * @param creator The creator of the XLine
- * @param expires When this should expire
- * @param reaosn The reason
- * @return A pointer to the XLine
- */
- virtual XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason);
-
- private:
- /** Delete an XLine, eg, remove it from the IRCd.
- * @param x The xline
- */
- virtual void Del(XLine *x);
-
- public:
/** Checks if a mask can/should be added to the XLineManager
* @param mask The mask
* @param expires When the mask would expire
@@ -164,6 +154,11 @@ class CoreExport XLineManager : public Service<XLineManager>
* @param x The xline
*/
virtual void Send(User *u, XLine *x) = 0;
+
+ /** Called to remove an XLine from the IRCd
+ * @param x The XLine
+ */
+ virtual void SendDel(XLine *x) = 0;
};
#endif // OPER_H
diff --git a/modules/commands/os_akill.cpp b/modules/commands/os_akill.cpp
index 99aa60089..3b82fb5fb 100644
--- a/modules/commands/os_akill.cpp
+++ b/modules/commands/os_akill.cpp
@@ -208,7 +208,14 @@ class CommandOSAKill : public Command
if (Config->AddAkiller)
reason = "[" + u->nick + "] " + reason;
- XLine *x = akills->Add(mask, u->nick, expires, reason);
+ Anope::string id;
+ if (Config->AkillIds)
+ {
+ id = XLineManager::GenerateUID();
+ reason = reason + " (ID: " + id + ")";
+ }
+
+ XLine *x = new XLine(mask, u->nick, expires, reason, id);
EventReturn MOD_RESULT;
FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, akills));
@@ -218,9 +225,13 @@ class CommandOSAKill : public Command
return;
}
+ akills->AddXLine(x);
+ if (Config->AkillOnAdd)
+ akills->Send(NULL, x);
+
source.Reply(_("\002%s\002 added to the AKILL list."), mask.c_str());
- Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
+ Log(LOG_ADMIN, u, this) << "on " << mask << " (" << x->Reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
if (readonly)
source.Reply(READ_ONLY_MODE);
@@ -266,8 +277,9 @@ class CommandOSAKill : public Command
FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, x, akills));
+ source.Reply(_("\002%s\002 deleted from the AKILL list."), x->Mask.c_str());
AkillDelCallback::DoDel(source, x);
- source.Reply(_("\002%s\002 deleted from the AKILL list."), mask.c_str());
+
}
if (readonly)
@@ -299,7 +311,7 @@ class CommandOSAKill : public Command
{
XLine *x = akills->GetEntry(i);
- if (mask.empty() || mask.equals_ci(x->Mask) || Anope::Match(x->Mask, mask))
+ if (mask.empty() || mask.equals_ci(x->Mask) || mask == x->UID || Anope::Match(x->Mask, mask))
{
if (!SentHeader)
{
@@ -344,7 +356,7 @@ class CommandOSAKill : public Command
{
XLine *x = akills->GetEntry(i);
- if (mask.empty() || mask.equals_ci(x->Mask) || Anope::Match(x->Mask, mask))
+ if (mask.empty() || mask.equals_ci(x->Mask) || mask == x->UID || Anope::Match(x->Mask, mask))
{
if (!SentHeader)
{
@@ -377,9 +389,9 @@ class CommandOSAKill : public Command
{
this->SetDesc(_("Manipulate the AKILL list"));
this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037 \037reason\037"));
- this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037}"));
- this->SetSyntax(_("LIST [\037mask\037 | \037list\037]"));
- this->SetSyntax(_("VIEW [\037mask\037 | \037list\037]"));
+ this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}"));
+ this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]"));
+ this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]"));
this->SetSyntax(_("CLEAR"));
}
diff --git a/modules/commands/os_chankill.cpp b/modules/commands/os_chankill.cpp
index 53e7dfd9c..e6b69cb9f 100644
--- a/modules/commands/os_chankill.cpp
+++ b/modules/commands/os_chankill.cpp
@@ -80,7 +80,8 @@ class CommandOSChanKill : public Command
if (uc->user->server == Me || uc->user->HasMode(UMODE_OPER))
continue;
- akills->Add("*@" + uc->user->host, u->nick, expires, realreason);
+ XLine *x = new XLine("*@" + uc->user->host, u->nick, expires, realreason, XLineManager::GenerateUID());
+ akills->AddXLine(x);
akills->Check(uc->user);
}
diff --git a/modules/commands/os_defcon.cpp b/modules/commands/os_defcon.cpp
index 4966f9e78..f97dfab92 100644
--- a/modules/commands/os_defcon.cpp
+++ b/modules/commands/os_defcon.cpp
@@ -424,9 +424,9 @@ class OSDefcon : public Module
if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && akills)
{
Log(findbot(Config->OperServ), "operserv/defcon") << "DEFCON: adding akill for *@" << u->host;
- XLine *x = akills->Add("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason);
- if (x)
- x->By = Config->OperServ;
+ XLine *x = new XLine("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason, XLineManager::GenerateUID());
+ x->By = Config->OperServ;
+ akills->AddXLine(x);
}
if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
@@ -518,9 +518,9 @@ class OSDefcon : public Module
if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && akills)
{
Log(findbot(Config->OperServ), "operserv/defcon") << "DEFCON: adding akill for *@" << u->host;
- XLine *x = akills->Add("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason);
- if (x)
- x->By = Config->OperServ;
+ XLine x("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason, XLineManager::GenerateUID());
+ x.By = Config->OperServ;
+ akills->Send(NULL, &x);
}
if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
{
@@ -528,23 +528,15 @@ class OSDefcon : public Module
return;
}
- if (!DConfig.sessionlimit)
- return;
-
- if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && akills)
- {
- Log(findbot(Config->OperServ), "operserv/defcon") << "DEFCON: adding akill for *@" << u->host;
- XLine *x = akills->Add("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, !DConfig.akillreason.empty() ? DConfig.akillreason : "DEFCON AKILL");
- if (x)
- x->By = Config->OperServ;
- }
-
if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
{
u->Kill(Config->OperServ, DConfig.akillreason);
return;
}
+ if (!DConfig.sessionlimit)
+ return;
+
Session *session = session_service->FindSession(u->host);
Exception *exception = session_service->FindException(u);
@@ -561,7 +553,8 @@ class OSDefcon : public Module
++session->hits;
if (akills && Config->MaxSessionKill && session->hits >= Config->MaxSessionKill)
{
- akills->Add("*@" + u->host, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Defcon session limit exceeded");
+ XLine x("*@" + u->host, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Defcon session limit exceeded", XLineManager::GenerateUID());
+ akills->Send(NULL, &x);
ircdproto->SendGlobops(findbot(Config->OperServ), "[DEFCON] Added a temporary AKILL for \2*@%s\2 due to excessive connections", u->host.c_str());
}
}
diff --git a/modules/commands/os_session.cpp b/modules/commands/os_session.cpp
index a6a2d2396..edaf841d5 100644
--- a/modules/commands/os_session.cpp
+++ b/modules/commands/os_session.cpp
@@ -679,7 +679,9 @@ class OSSession : public Module
if (Config->MaxSessionKill && session->hits >= Config->MaxSessionKill && akills)
{
const Anope::string &akillmask = "*@" + u->host;
- akills->Add(akillmask, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Session limit exceeded");
+ XLine *x = new XLine(akillmask, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Session limit exceeded", XLineManager::GenerateUID());
+ akills->AddXLine(x);
+ akills->Send(NULL, x);
if (bi)
ircdproto->SendGlobops(bi, "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask.c_str());
}
diff --git a/modules/commands/os_sxline.cpp b/modules/commands/os_sxline.cpp
index 80ad9db8c..56444383d 100644
--- a/modules/commands/os_sxline.cpp
+++ b/modules/commands/os_sxline.cpp
@@ -205,7 +205,7 @@ class CommandOSSXLineBase : public Command
{
XLine *x = this->xlm()->GetEntry(i);
- if (mask.empty() || mask.equals_ci(x->Mask) || Anope::Match(x->Mask, mask))
+ if (mask.empty() || mask.equals_ci(x->Mask) || mask == x->UID || Anope::Match(x->Mask, mask))
{
if (!SentHeader)
{
@@ -249,7 +249,7 @@ class CommandOSSXLineBase : public Command
{
XLine *x = this->xlm()->GetEntry(i);
- if (mask.empty() || mask.equals_ci(x->Mask) || Anope::Match(x->Mask, mask))
+ if (mask.empty() || mask.equals_ci(x->Mask) || mask == x->UID || Anope::Match(x->Mask, mask))
{
if (!SentHeader)
{
@@ -278,14 +278,9 @@ class CommandOSSXLineBase : public Command
return;
}
public:
- CommandOSSXLineBase(Module *creator, const Anope::string &cmd) : Command(creator, cmd, 1, 3)
+ CommandOSSXLineBase(Module *creator, const Anope::string &cmd) : Command(creator, cmd, 1, 4)
{
this->SetDesc(Anope::printf(_("Manipulate the %s list"), cmd.c_str()));
- this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037:\037reason\037"));
- this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037}"));
- this->SetSyntax(_("LIST [\037mask\037 | \037list\037]"));
- this->SetSyntax(_("VIEW [\037mask\037 | \037list\037]"));
- this->SetSyntax(_("CLEAR"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
@@ -410,7 +405,14 @@ class CommandOSSNLine : public CommandOSSXLineBase
if (Config->AddAkiller)
reason = "[" + u->nick + "] " + reason;
- XLine *x = this->xlm()->Add(mask, u->nick, expires, reason);
+ Anope::string id;
+ if (Config->AkillIds)
+ {
+ id = XLineManager::GenerateUID();
+ reason = reason + " (ID: " + id + ")";
+ }
+
+ XLine *x = new XLine(mask, u->nick, expires, reason, id);
EventReturn MOD_RESULT;
FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, this->xlm()));
@@ -420,6 +422,21 @@ class CommandOSSNLine : public CommandOSSXLineBase
return;
}
+ this->xlm()->AddXLine(x);
+ if (Config->KillonSNline && !ircd->sglineenforce)
+ {
+ Anope::string rreason = "G-Lined: " + reason;
+
+ for (Anope::insensitive_map<User *>::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
+ {
+ User *user = it->second;
+ ++it;
+
+ if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->realname, x->Mask))
+ user->Kill(Config->ServerName, rreason);
+ }
+ }
+
source.Reply(_("\002%s\002 added to the %s list."), mask.c_str(), this->name.c_str());
Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
@@ -438,6 +455,11 @@ class CommandOSSNLine : public CommandOSSXLineBase
public:
CommandOSSNLine(Module *creator) : CommandOSSXLineBase(creator, "operserv/snline"), snlines("xlinemanager/snline")
{
+ this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037:\037reason\037"));
+ this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}"));
+ this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]"));
+ this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]"));
+ this->SetSyntax(_("CLEAR"));
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -494,7 +516,7 @@ class CommandOSSQLine : public CommandOSSXLineBase
void OnAdd(CommandSource &source, const std::vector<Anope::string> &params)
{
- if (!this->xlm() ||! ircd->sqline)
+ if (!this->xlm() || !ircd->sqline)
{
source.Reply(_("Your IRCd does not support SQLINE"));
return;
@@ -563,7 +585,10 @@ class CommandOSSQLine : public CommandOSSXLineBase
return;
}
- XLine *x = this->sqlines->Add(mask, u->nick, expires, reason);
+ Anope::string id = XLineManager::GenerateUID();
+ reason = reason + " (ID: " + id + ")";
+
+ XLine *x = new XLine(mask, u->nick, expires, reason, id);
EventReturn MOD_RESULT;
FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, this->xlm()));
@@ -573,6 +598,44 @@ class CommandOSSQLine : public CommandOSSXLineBase
return;
}
+ this->xlm()->AddXLine(x);
+ if (Config->KillonSQline)
+ {
+ Anope::string rreason = "Q-Lined: " + reason;
+
+ if (mask[0] == '#')
+ {
+ for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit)
+ {
+ Channel *c = cit->second;
+
+ if (!Anope::Match(c->name, mask))
+ continue;
+ for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
+ {
+ UserContainer *uc = *it;
+ ++it;
+
+ if (uc->user->HasMode(UMODE_OPER) || uc->user->server == Me)
+ continue;
+ c->Kick(NULL, uc->user, "%s", reason.c_str());
+ }
+ }
+ }
+ else
+ {
+ for (Anope::insensitive_map<User *>::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
+ {
+ User *user = it->second;
+ ++it;
+
+ if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->nick, x->Mask))
+ user->Kill(Config->ServerName, rreason);
+ }
+ }
+ }
+ this->xlm()->Send(NULL, x);
+
source.Reply(_("\002%s\002 added to the SQLINE list."), mask.c_str());
Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
@@ -591,6 +654,11 @@ class CommandOSSQLine : public CommandOSSXLineBase
public:
CommandOSSQLine(Module *creator) : CommandOSSXLineBase(creator, "operserv/sqline"), sqlines("xlinemanager/sqline")
{
+ this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037 \037reason\037"));
+ this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}"));
+ this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]"));
+ this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]"));
+ this->SetSyntax(_("CLEAR"));
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
diff --git a/modules/database/db_old.cpp b/modules/database/db_old.cpp
index 55956da78..440713a6e 100644
--- a/modules/database/db_old.cpp
+++ b/modules/database/db_old.cpp
@@ -920,9 +920,9 @@ static void LoadOper()
if (!akill)
continue;
- XLine *x = akill->Add(user + "@" + host, by, expires, reason);
- if (x)
- x->Created = seton;
+ XLine *x = new XLine(user + "@" + host, by, expires, reason, XLineManager::GenerateUID());
+ x->Created = seton;
+ akill->AddXLine(x);
}
read_int16(&capacity, f); // SNLines
@@ -940,9 +940,9 @@ static void LoadOper()
if (!snline)
continue;
- XLine *x = snline->Add(mask, by, expires, reason);
- if (x)
- x->Created = seton;
+ XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID());
+ x->Created = seton;
+ snline->AddXLine(x);
}
read_int16(&capacity, f); // SQLines
@@ -960,9 +960,9 @@ static void LoadOper()
if (!sqline)
continue;
- XLine *x = sqline->Add(mask, by, expires, reason);
- if (x)
- x->Created = seton;
+ XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID());
+ x->Created = seton;
+ sqline->AddXLine(x);
}
read_int16(&capacity, f); // SZLines
@@ -980,9 +980,9 @@ static void LoadOper()
if (!szline)
continue;
- XLine *x = szline->Add(mask, by, expires, reason);
- if (x)
- x->Created = seton;
+ XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID());
+ x->Created = seton;
+ szline->AddXLine(x);
}
close_db(f);
diff --git a/modules/database/db_plain.cpp b/modules/database/db_plain.cpp
index 4ac109018..3605c0b9d 100644
--- a/modules/database/db_plain.cpp
+++ b/modules/database/db_plain.cpp
@@ -548,9 +548,9 @@ static void LoadOperInfo(const std::vector<Anope::string> &params)
time_t expires = params[6].is_pos_number_only() ? convertTo<time_t>(params[6]) : 0;
Anope::string reason = params[7];
- XLine *x = xl->Add(mask, by, expires, reason);
- if (x)
- x->Created = seton;
+ XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID());
+ x->Created = seton;
+ xl->AddXLine(x);
break;
}
}
diff --git a/modules/extra/m_dnsbl.cpp b/modules/extra/m_dnsbl.cpp
index 894eebb8a..4be489aa7 100644
--- a/modules/extra/m_dnsbl.cpp
+++ b/modules/extra/m_dnsbl.cpp
@@ -63,17 +63,16 @@ class DNSBLResolver : public DNSRequest
BotInfo *operserv = findbot(Config->OperServ);
Log(operserv) << "DNSBL: " << user->GetMask() << " appears in " << this->blacklist.name;
+ XLine *x = new XLine("*@" + user->host, Config->OperServ, Anope::CurTime + this->blacklist.bantime, reason, XLineManager::GenerateUID());
if (this->add_to_akill && akills)
{
- XLine *x = akills->Add("*@" + user->host, Config->OperServ, Anope::CurTime + this->blacklist.bantime, reason);
- /* If AkillOnAdd is disabled send it anyway, noone wants bots around... */
- if (!Config->AkillOnAdd)
- akills->Send(NULL, x);
+ akills->AddXLine(x);
+ akills->Send(NULL, x);
}
else
{
- XLine xline("*@" + user->host, Config->OperServ, Anope::CurTime + this->blacklist.bantime, reason);
- ircdproto->SendAkill(NULL, &xline);
+ ircdproto->SendAkill(NULL, x);
+ delete x;
}
}
};
diff --git a/modules/extra/m_proxyscan.cpp b/modules/extra/m_proxyscan.cpp
index 1964e6bf0..685d984b0 100644
--- a/modules/extra/m_proxyscan.cpp
+++ b/modules/extra/m_proxyscan.cpp
@@ -86,20 +86,19 @@ class ProxyConnect : public ConnectionSocket
reason = reason.replace_all_cs("%p", stringify(this->conaddr.port()));
Log(findbot(Config->OperServ)) << "PROXYSCAN: Open " << this->GetType() << " proxy found on " << this->conaddr.addr() << ":" << this->conaddr.port() << " (" << reason << ")";
+ XLine *x = new XLine("*@" + this->conaddr.addr(), Config->OperServ, Anope::CurTime + this->proxy.duration, reason, XLineManager::GenerateUID());
if (add_to_akill && akills)
{
- XLine *x = akills->Add("*@" + this->conaddr.addr(), Config->OperServ, Anope::CurTime + this->proxy.duration, reason);
- /* If AkillOnAdd is disabled send it anyway, noone wants bots around... */
- if (!Config->AkillOnAdd)
- akills->Send(NULL, x);
+ akills->AddXLine(x);
+ akills->Send(NULL, x);
}
else
{
- XLine xline("*@" + this->conaddr.addr(), Config->OperServ, Anope::CurTime + this->proxy.duration, reason);
if (ircd->szline)
- ircdproto->SendSZLine(NULL, &xline);
+ ircdproto->SendSZLine(NULL, x);
else
- ircdproto->SendAkill(NULL, &xline);
+ ircdproto->SendAkill(NULL, x);
+ delete x;
}
}
};
diff --git a/modules/pseudoclients/operserv.cpp b/modules/pseudoclients/operserv.cpp
index 6dfacd19f..d29c2c66e 100644
--- a/modules/pseudoclients/operserv.cpp
+++ b/modules/pseudoclients/operserv.cpp
@@ -20,19 +20,20 @@ class SGLineManager : public XLineManager
public:
SGLineManager(Module *creator) : XLineManager(creator, "xlinemanager/sgline", 'G') { }
- XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason)
+ void OnMatch(User *u, XLine *x)
{
- XLine *x = new XLine(mask, creator, expires, reason);
-
- this->AddXLine(x);
-
- if (UplinkSock && Config->AkillOnAdd)
- this->Send(NULL, x);
-
- return x;
+ if (u)
+ u->Kill(Config->OperServ, x->Reason);
+ this->Send(u, x);
}
- void Del(XLine *x)
+ void OnExpire(XLine *x)
+ {
+ if (Config->WallAkillExpire)
+ ircdproto->SendGlobops(OperServ, "AKILL on %s has expired", x->Mask.c_str());
+ }
+
+ void Send(User *u, XLine *x)
{
try
{
@@ -41,28 +42,15 @@ class SGLineManager : public XLineManager
else if (x->GetUser() != "*")
throw SocketException("Can not ZLine a username");
x->GetIP();
- ircdproto->SendSZLineDel(x);
+ ircdproto->SendSZLine(u, x);
}
catch (const SocketException &)
{
- ircdproto->SendAkillDel(x);
+ ircdproto->SendAkill(u, x);
}
}
- void OnMatch(User *u, XLine *x)
- {
- if (u)
- u->Kill(Config->OperServ, x->Reason);
- this->Send(u, x);
- }
-
- void OnExpire(XLine *x)
- {
- if (Config->WallAkillExpire)
- ircdproto->SendGlobops(OperServ, "AKILL on %s has expired", x->Mask.c_str());
- }
-
- void Send(User *u, XLine *x)
+ void SendDel(XLine *x)
{
try
{
@@ -71,11 +59,11 @@ class SGLineManager : public XLineManager
else if (x->GetUser() != "*")
throw SocketException("Can not ZLine a username");
x->GetIP();
- ircdproto->SendSZLine(u, x);
+ ircdproto->SendSZLineDel(x);
}
catch (const SocketException &)
{
- ircdproto->SendAkill(u, x);
+ ircdproto->SendAkillDel(x);
}
}
};
@@ -85,59 +73,6 @@ class SQLineManager : public XLineManager
public:
SQLineManager(Module *creator) : XLineManager(creator, "xlinemanager/sqline", 'Q') { }
- XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason)
- {
- XLine *x = new XLine(mask, creator, expires, reason);
-
- this->AddXLine(x);
-
- if (Config->KillonSQline)
- {
- Anope::string rreason = "Q-Lined: " + reason;
-
- if (mask[0] == '#')
- {
- for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit)
- {
- Channel *c = cit->second;
-
- if (!Anope::Match(c->name, mask))
- continue;
- for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
- {
- UserContainer *uc = *it;
- ++it;
-
- if (uc->user->HasMode(UMODE_OPER) || uc->user->server == Me)
- continue;
- c->Kick(NULL, uc->user, "%s", reason.c_str());
- }
- }
- }
- else
- {
- for (Anope::insensitive_map<User *>::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
- {
- User *user = it->second;
- ++it;
-
- if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->nick, x->Mask))
- user->Kill(Config->ServerName, rreason);
- }
- }
- }
-
- if (UplinkSock)
- this->Send(NULL, x);
-
- return x;
- }
-
- void Del(XLine *x)
- {
- ircdproto->SendSQLineDel(x);
- }
-
void OnMatch(User *u, XLine *x)
{
if (u)
@@ -160,6 +95,11 @@ class SQLineManager : public XLineManager
ircdproto->SendSQLine(u, x);
}
+ void SendDel(XLine *x)
+ {
+ ircdproto->SendSQLineDel(x);
+ }
+
bool CheckChannel(Channel *c)
{
if (ircd->chansqline)
@@ -175,34 +115,6 @@ class SNLineManager : public XLineManager
public:
SNLineManager(Module *creator) : XLineManager(creator, "xlinemanager/snline", 'N') { }
- XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason)
- {
- XLine *x = new XLine(mask, creator, expires, reason);
-
- this->AddXLine(x);
-
- if (Config->KillonSNline && !ircd->sglineenforce)
- {
- Anope::string rreason = "G-Lined: " + reason;
-
- for (Anope::insensitive_map<User *>::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
- {
- User *user = it->second;
- ++it;
-
- if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->realname, x->Mask))
- user->Kill(Config->ServerName, rreason);
- }
- }
-
- return x;
- }
-
- void Del(XLine *x)
- {
- ircdproto->SendSGLineDel(x);
- }
-
void OnMatch(User *u, XLine *x)
{
if (u)
@@ -224,18 +136,21 @@ class SNLineManager : public XLineManager
ircdproto->SendSGLine(u, x);
}
+ void SendDel(XLine *x)
+ {
+ ircdproto->SendSGLineDel(x);
+ }
+
XLine *Check(User *u)
{
- for (unsigned i = this->XLines.size(); i > 0; --i)
+ for (unsigned i = this->GetList().size(); i > 0; --i)
{
- XLine *x = this->XLines[i - 1];
+ XLine *x = this->GetList()[i - 1];
if (x->Expires && x->Expires < Anope::CurTime)
{
this->OnExpire(x);
- this->Del(x);
- delete x;
- this->XLines.erase(XLines.begin() + i - 1);
+ this->DelXLine(x);
continue;
}
diff --git a/src/config.cpp b/src/config.cpp
index f9139bf7a..bbfb6890d 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -1265,6 +1265,7 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"operserv", "maxsessionkill", "0", new ValueContainerUInt(&conf->MaxSessionKill), DT_UINTEGER, NoValidation},
{"operserv", "sessionautokillexpiry", "0", new ValueContainerTime(&conf->SessionAutoKillExpiry), DT_TIME, NoValidation},
{"operserv", "addakiller", "no", new ValueContainerBool(&conf->AddAkiller), DT_BOOLEAN, NoValidation},
+ {"operserv", "akillids", "no", new ValueContainerBool(&conf->AkillIds), DT_BOOLEAN, NoValidation},
{"operserv", "opersonly", "no", new ValueContainerBool(&conf->OSOpersOnly), DT_BOOLEAN, NoValidation},
{"global", "name", "", new ValueContainerString(&conf->Global), DT_STRING, NoValidation},
{"global", "globaloncycle", "no", new ValueContainerBool(&conf->GlobalOnCycle), DT_BOOLEAN, NoValidation},
diff --git a/src/operserv.cpp b/src/operserv.cpp
index b0db3aee1..05d27d6ca 100644
--- a/src/operserv.cpp
+++ b/src/operserv.cpp
@@ -15,17 +15,20 @@
/* List of XLine managers we check users against in XLineManager::CheckAll */
std::list<XLineManager *> XLineManager::XLineManagers;
+std::map<Anope::string, XLine *, std::less<ci::string> > XLineManager::XLinesByUID;
XLine::XLine()
{
}
-XLine::XLine(const Anope::string &mask, const Anope::string &reason) : Mask(mask), Created(0), Expires(0), Reason(reason)
+XLine::XLine(const Anope::string &mask, const Anope::string &reason, const Anope::string &uid) : Mask(mask), Created(0), Expires(0), Reason(reason), UID(uid)
{
+ manager = NULL;
}
-XLine::XLine(const Anope::string &mask, const Anope::string &by, const time_t expires, const Anope::string &reason) : Mask(mask), By(by), Created(Anope::CurTime), Expires(expires), Reason(reason)
+XLine::XLine(const Anope::string &mask, const Anope::string &by, const time_t expires, const Anope::string &reason, const Anope::string &uid) : Mask(mask), By(by), Created(Anope::CurTime), Expires(expires), Reason(reason), UID(uid)
{
+ manager = NULL;
}
Anope::string XLine::GetNick() const
@@ -79,7 +82,9 @@ SerializableBase::serialized_data XLine::serialize()
data["created"] << this->Created;
data["expires"] << this->Expires;
data["reason"] << this->Reason;
- data["manager"] << this->Manager;
+ data["uid"] << this->UID;
+ if (this->manager)
+ data["manager"] << this->manager->name;
return data;
}
@@ -97,38 +102,18 @@ void XLine::unserialize(SerializableBase::serialized_data &data)
data["created"] >> xl->Created;
data["expires"] >> xl->Expires;
data["reason"] >> xl->Reason;
+ data["uid"] >> xl->UID;
+ xl->manager = xlm;
xlm->AddXLine(xl);
}
-/** Constructor
- */
-XLineManager::XLineManager(Module *creator, const Anope::string &xname, char t) : Service<XLineManager>(creator, xname), type(t)
-{
-}
-
-/** Destructor
- * Clears all XLines in this XLineManager
- */
-XLineManager::~XLineManager()
-{
- this->Clear();
-}
-
-/** The type of xline provided by this service
- * @return The type
+/** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll
+ * It is important XLineManagers are registered in the proper order. Eg, if you had one akilling
+ * clients and one handing them free olines, you would want the akilling one first. This way if a client
+ * matches an entry on both of the XLineManagers, they would be akilled.
+ * @param xlm THe XLineManager
*/
-const char &XLineManager::Type()
-{
- return this->type;
-}
-
- /** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll
- * It is important XLineManagers are registered in the proper order. Eg, if you had one akilling
- * clients and one handing them free olines, you would want the akilling one first. This way if a client
- * matches an entry on both of the XLineManagers, they would be akilled.
- * @param xlm THe XLineManager
- */
void XLineManager::RegisterXLineManager(XLineManager *xlm)
{
XLineManagers.push_back(xlm);
@@ -173,6 +158,43 @@ std::pair<XLineManager *, XLine *> XLineManager::CheckAll(User *u)
return ret;
}
+Anope::string XLineManager::GenerateUID()
+{
+ Anope::string id;
+ for (int i = 0; i < 10; ++i)
+ {
+ char c;
+ do
+ c = getrandom8();
+ while (!isupper(c) && !isdigit(c));
+ id += c;
+ }
+
+ return id;
+}
+
+/** Constructor
+ */
+XLineManager::XLineManager(Module *creator, const Anope::string &xname, char t) : Service<XLineManager>(creator, xname), type(t)
+{
+}
+
+/** Destructor
+ * Clears all XLines in this XLineManager
+ */
+XLineManager::~XLineManager()
+{
+ this->Clear();
+}
+
+/** The type of xline provided by this service
+ * @return The type
+ */
+const char &XLineManager::Type()
+{
+ return this->type;
+}
+
/** Get the number of XLines in this XLineManager
* @return The number of XLines
*/
@@ -194,7 +216,9 @@ const std::vector<XLine *> &XLineManager::GetList() const
*/
void XLineManager::AddXLine(XLine *x)
{
- x->Manager = this->name;
+ x->manager = this;
+ if (!x->UID.empty())
+ XLinesByUID[x->UID] = x;
this->XLines.push_back(x);
}
@@ -206,9 +230,12 @@ bool XLineManager::DelXLine(XLine *x)
{
std::vector<XLine *>::iterator it = std::find(this->XLines.begin(), this->XLines.end(), x);
+ if (!x->UID.empty())
+ XLinesByUID.erase(x->UID);
+
if (it != this->XLines.end())
{
- this->Del(x);
+ this->SendDel(x);
delete x;
this->XLines.erase(it);
@@ -236,29 +263,14 @@ XLine *XLineManager::GetEntry(unsigned index)
void XLineManager::Clear()
{
for (unsigned i = 0; i < this->XLines.size(); ++i)
+ {
+ if (!this->XLines[i]->UID.empty())
+ XLinesByUID.erase(this->XLines[i]->UID);
delete this->XLines[i];
+ }
this->XLines.clear();
}
-/** Add an entry to this XLine Manager
- * @param mask The mask of the XLine
- * @param creator The creator of the XLine
- * @param expires When this should expire
- * @param reaosn The reason
- * @return A pointer to the XLine
- */
-XLine *XLineManager::Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason)
-{
- return NULL;
-}
-
-/** Delete an XLine, eg, remove it from the IRCd.
- * @param x The xline
- */
-void XLineManager::Del(XLine *x)
-{
-}
-
/** Checks if a mask can/should be added to the XLineManager
* @param mask The mask
* @param expires When the mask would expire
@@ -315,6 +327,9 @@ std::pair<int, XLine *> XLineManager::CanAdd(const Anope::string &mask, time_t e
*/
XLine *XLineManager::HasEntry(const Anope::string &mask)
{
+ std::map<Anope::string, XLine *, std::less<ci::string> >::iterator it = XLinesByUID.find(mask);
+ if (it != XLinesByUID.end() && (it->second->manager == NULL || it->second->manager == this))
+ return it->second;
for (unsigned i = 0, end = this->XLines.size(); i < end; ++i)
{
XLine *x = this->XLines[i];
@@ -339,9 +354,7 @@ XLine *XLineManager::Check(User *u)
if (x->Expires && x->Expires < Anope::CurTime)
{
this->OnExpire(x);
- this->Del(x);
- delete x;
- this->XLines.erase(XLines.begin() + i - 1);
+ this->DelXLine(x);
continue;
}