summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2011-05-01 18:41:54 -0400
committerAdam <Adam@anope.org>2011-05-01 18:41:54 -0400
commit4a3c64291f683823a1f8977c00f57b57af577f03 (patch)
tree53129214f4d48bc3a661d7e1a83c60576758cb46
parent036b3c9053d663b0714690db33161e2df9e76782 (diff)
Fixed sometimes not removing nick masks from the access list when the group is dropped
-rw-r--r--include/language.h2
-rw-r--r--include/regchannel.h38
-rw-r--r--include/services.h40
-rw-r--r--modules/core/cs_access.cpp26
-rw-r--r--modules/core/cs_clone.cpp2
-rw-r--r--modules/core/cs_xop.cpp16
-rw-r--r--modules/core/db_plain.cpp2
-rw-r--r--modules/core/ns_group.cpp4
-rw-r--r--modules/extra/db_mysql.cpp8
-rw-r--r--src/regchannel.cpp45
10 files changed, 102 insertions, 81 deletions
diff --git a/include/language.h b/include/language.h
index 409ffc7d4..f4329a72b 100644
--- a/include/language.h
+++ b/include/language.h
@@ -48,7 +48,7 @@
#define NICK_ALREADY_REGISTERED "Nickname \002%s\002 is already registered!"
#define NICK_SET_SYNTAX "SET \037option\037 \037parameters\037"
#define NICK_SET_DISABLED "Sorry, nickname option setting is temporarily disabled."
-#define NICK_SET_UNKNOWN_OPTION "Unknown SET option \002%s\002."
+#define NICK_SET_UNKNOWN_OPTION "Unknown SET option \002%s%s\002."
#define NICK_SET_DISPLAY_CHANGED "The new display is now \002%s\002."
#define NICK_SASET_SYNTAX "SASET \037nickname\037 \037option\037 \037parameters\037"
#define NICK_SASET_DISPLAY_INVALID "The new display for \002%s\002 MUST be a nickname of the nickname group!"
diff --git a/include/regchannel.h b/include/regchannel.h
index f2eaf5952..f662381c0 100644
--- a/include/regchannel.h
+++ b/include/regchannel.h
@@ -68,6 +68,44 @@ const Anope::string ChannelInfoFlagStrings[] = {
"SIGNKICK", "SIGNKICK_LEVEL", "XOP", "SUSPENDED", "PERSIST", ""
};
+class ChanAccess
+{
+ Anope::string mask; /* Mask of the access entry */
+ public:
+ int16 level;
+ NickCore *nc; /* NC of the entry, if the entry is a valid nickcore */
+ time_t last_seen;
+ Anope::string creator;
+
+ ChanAccess(const Anope::string &umask);
+ const Anope::string &GetMask();
+};
+
+/** Flags for auto kick
+ */
+enum AutoKickFlag
+{
+ /* Is by nick core, not mask */
+ AK_ISNICK
+};
+
+const Anope::string AutoKickFlagString[] = { "AK_ISNICK", "" };
+
+/* AutoKick data. */
+class AutoKick : public Flags<AutoKickFlag>
+{
+ public:
+ AutoKick() : Flags<AutoKickFlag>(AutoKickFlagString) { }
+ /* Only one of these can be in use */
+ Anope::string mask;
+ NickCore *nc;
+
+ Anope::string reason;
+ Anope::string creator;
+ time_t addtime;
+ time_t last_used;
+};
+
struct ModeLock
{
bool set;
diff --git a/include/services.h b/include/services.h
index b83790355..6caa06d48 100644
--- a/include/services.h
+++ b/include/services.h
@@ -557,46 +557,6 @@ enum AccessLevel
ACCESS_QOP = 10000
};
-/* Channel info structures. Stored similarly to the nicks, except that
- * the second character of the channel name, not the first, is used to
- * determine the list. (Hashing based on the first character of the name
- * wouldn't get very far. ;) ) */
-
-/* Access levels for users. */
-struct ChanAccess
-{
- int16 level;
- Anope::string mask; /* Mask of the access entry */
- NickCore *nc; /* NC of the entry, if the entry is a valid nickcore */
- time_t last_seen;
- Anope::string creator;
-};
-
-/** Flags for auto kick
- */
-enum AutoKickFlag
-{
- /* Is by nick core, not mask */
- AK_ISNICK
-};
-
-const Anope::string AutoKickFlagString[] = { "AK_ISNICK", "" };
-
-/* AutoKick data. */
-class AutoKick : public Flags<AutoKickFlag>
-{
- public:
- AutoKick() : Flags<AutoKickFlag>(AutoKickFlagString) { }
- /* Only one of these can be in use */
- Anope::string mask;
- NickCore *nc;
-
- Anope::string reason;
- Anope::string creator;
- time_t addtime;
- time_t last_used;
-};
-
/** Flags for badwords
*/
enum BadWordType
diff --git a/modules/core/cs_access.cpp b/modules/core/cs_access.cpp
index 9033fc51d..0cf8263ac 100644
--- a/modules/core/cs_access.cpp
+++ b/modules/core/cs_access.cpp
@@ -50,10 +50,10 @@ class AccessListCallback : public NumberList
if (source.ci->HasFlag(CI_XOP))
{
Anope::string xop = get_xop_level(access->level);
- source.Reply(_(" %3d %s %s"), Number + 1, xop.c_str(), access->mask.c_str());
+ source.Reply(_(" %3d %s %s"), Number + 1, xop.c_str(), access->GetMask().c_str());
}
else
- source.Reply(_(" %3d %4d %s"), Number + 1, access->level, access->mask.c_str());
+ source.Reply(_(" %3d %4d %s"), Number + 1, access->level, access->GetMask().c_str());
}
};
@@ -92,10 +92,10 @@ class AccessViewCallback : public AccessListCallback
if (ci->HasFlag(CI_XOP))
{
Anope::string xop = get_xop_level(access->level);
- source.Reply(_(CHAN_ACCESS_VIEW_XOP_FORMAT), Number + 1, xop.c_str(), access->mask.c_str(), access->creator.c_str(), timebuf.c_str());
+ source.Reply(_(CHAN_ACCESS_VIEW_XOP_FORMAT), Number + 1, xop.c_str(), access->GetMask().c_str(), access->creator.c_str(), timebuf.c_str());
}
else
- source.Reply(_(CHAN_ACCESS_VIEW_AXS_FORMAT), Number + 1, access->level, access->mask.c_str(), access->creator.c_str(), timebuf.c_str());
+ source.Reply(_(CHAN_ACCESS_VIEW_AXS_FORMAT), Number + 1, access->level, access->GetMask().c_str(), access->creator.c_str(), timebuf.c_str());
}
};
@@ -151,9 +151,9 @@ class AccessDelCallback : public NumberList
++Deleted;
if (!Nicks.empty())
- Nicks += ", " + access->mask;
+ Nicks += ", " + access->GetMask();
else
- Nicks = access->mask;
+ Nicks = access->GetMask();
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
@@ -218,7 +218,7 @@ class CommandCSAccess : public Command
}
if (access->level == level)
{
- source.Reply(_("Access level for \002%s\002 on %s unchanged from \002%d\002."), access->mask.c_str(), ci->name.c_str(), level);
+ source.Reply(_("Access level for \002%s\002 on %s unchanged from \002%d\002."), access->GetMask().c_str(), ci->name.c_str(), level);
return MOD_CONT;
}
access->level = level;
@@ -226,7 +226,7 @@ class CommandCSAccess : public Command
FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, access));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << " (level: " << level << ") as level " << u_level;
- source.Reply(_("Access level for \002%s\002 on %s changed to \002%d\002."), access->mask.c_str(), ci->name.c_str(), level);
+ source.Reply(_("Access level for \002%s\002 on %s changed to \002%d\002."), access->GetMask().c_str(), ci->name.c_str(), level);
return MOD_CONT;
}
@@ -241,7 +241,7 @@ class CommandCSAccess : public Command
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, access));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << " (level: " << level << ") as level " << u_level;
- source.Reply(_("\002%s\002 added to %s access list at level \002%d\002."), access->mask.c_str(), ci->name.c_str(), level);
+ source.Reply(_("\002%s\002 added to %s access list at level \002%d\002."), access->GetMask().c_str(), ci->name.c_str(), level);
return MOD_CONT;
}
@@ -271,9 +271,9 @@ class CommandCSAccess : public Command
source.Reply(_(ACCESS_DENIED));
else
{
- source.Reply(_("\002%s\002 deleted from %s access list."), access->mask.c_str(), ci->name.c_str());
+ source.Reply(_("\002%s\002 deleted from %s access list."), access->GetMask().c_str(), ci->name.c_str());
bool override = !check_access(u, ci, CA_ACCESS_CHANGE) && access->nc != u->Account();
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << access->mask << " from level " << access->level;
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << access->GetMask() << " from level " << access->level;
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
@@ -305,7 +305,7 @@ class CommandCSAccess : public Command
{
ChanAccess *access = ci->GetAccess(i);
- if (!nick.empty() && !Anope::Match(access->mask, nick))
+ if (!nick.empty() && !Anope::Match(access->GetMask(), nick))
continue;
if (!SentHeader)
@@ -347,7 +347,7 @@ class CommandCSAccess : public Command
{
ChanAccess *access = ci->GetAccess(i);
- if (!nick.empty() && !Anope::Match(access->mask, nick))
+ if (!nick.empty() && !Anope::Match(access->GetMask(), nick))
continue;
if (!SentHeader)
diff --git a/modules/core/cs_clone.cpp b/modules/core/cs_clone.cpp
index 5b264c8df..bbdae4c5f 100644
--- a/modules/core/cs_clone.cpp
+++ b/modules/core/cs_clone.cpp
@@ -109,7 +109,7 @@ public:
for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
{
ChanAccess *access = ci->GetAccess(i);
- target_ci->AddAccess(access->mask, access->level, access->creator, access->last_seen);
+ target_ci->AddAccess(access->GetMask(), access->level, access->creator, access->last_seen);
}
source.Reply(_("All access entries from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
diff --git a/modules/core/cs_xop.cpp b/modules/core/cs_xop.cpp
index 48a3556cd..22ffb4f68 100644
--- a/modules/core/cs_xop.cpp
+++ b/modules/core/cs_xop.cpp
@@ -55,7 +55,7 @@ class XOPListCallback : public NumberList
static void DoList(CommandSource &source, ChanAccess *access, unsigned index, int level)
{
- source.Reply(_(" %3d %s"), index, access->mask.c_str());
+ source.Reply(_(" %3d %s"), index, access->GetMask().c_str());
}
};
@@ -95,9 +95,9 @@ class XOPDelCallback : public NumberList
++Deleted;
if (!Nicks.empty())
- Nicks += ", " + access->mask;
+ Nicks += ", " + access->GetMask();
else
- Nicks = access->mask;
+ Nicks = access->GetMask();
FOREACH_MOD(I_OnAccessDel, OnAccessDel(source.ci, source.u, access));
@@ -181,12 +181,12 @@ class XOPBase : public Command
if (!change)
{
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, access));
- source.Reply(("\002%s\002 added to %s %s list."), access->mask.c_str(), ci->name.c_str(), this->name.c_str());
+ source.Reply(("\002%s\002 added to %s %s list."), access->GetMask().c_str(), ci->name.c_str(), this->name.c_str());
}
else
{
FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, access));
- source.Reply(_("\002%s\002 moved to %s %s list."), access->mask.c_str(), ci->name.c_str(), this->name.c_str());
+ source.Reply(_("\002%s\002 moved to %s %s list."), access->GetMask().c_str(), ci->name.c_str(), this->name.c_str());
}
return MOD_CONT;
@@ -247,9 +247,9 @@ class XOPBase : public Command
else
{
bool override = ulev <= access->level;
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << access->mask;
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << access->GetMask();
- source.Reply(_("\002%s\002 deleted from %s %s list."), access->mask.c_str(), ci->name.c_str(), this->name.c_str());
+ source.Reply(_("\002%s\002 deleted from %s %s list."), access->GetMask().c_str(), ci->name.c_str(), this->name.c_str());
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
@@ -300,7 +300,7 @@ class XOPBase : public Command
if (access->level != level)
continue;
- else if (!nick.empty() && !Anope::Match(access->mask, nick))
+ else if (!nick.empty() && !Anope::Match(access->GetMask(), nick))
continue;
if (!SentHeader)
diff --git a/modules/core/db_plain.cpp b/modules/core/db_plain.cpp
index 2bad313ca..e4678a8d9 100644
--- a/modules/core/db_plain.cpp
+++ b/modules/core/db_plain.cpp
@@ -815,7 +815,7 @@ class DBPlain : public Module
if (ci->HasFlag(CI_FORBIDDEN))
db_buffer << "MD FORBID " << ci->forbidby << " :" << ci->forbidreason << endl;
for (unsigned k = 0, end = ci->GetAccessCount(); k < end; ++k)
- db_buffer << "MD ACCESS " << ci->GetAccess(k)->mask << " " << ci->GetAccess(k)->level << " " << ci->GetAccess(k)->last_seen << " " << ci->GetAccess(k)->creator << endl;
+ db_buffer << "MD ACCESS " << ci->GetAccess(k)->GetMask() << " " << ci->GetAccess(k)->level << " " << ci->GetAccess(k)->last_seen << " " << ci->GetAccess(k)->creator << endl;
for (unsigned k = 0, end = ci->GetAkickCount(); k < end; ++k)
{
db_buffer << "MD AKICK 0 " << (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? "NICK " : "MASK ") <<
diff --git a/modules/core/ns_group.cpp b/modules/core/ns_group.cpp
index ac891588d..c7a56cb8f 100644
--- a/modules/core/ns_group.cpp
+++ b/modules/core/ns_group.cpp
@@ -83,7 +83,9 @@ class CommandNSGroup : public Command
else
{
bool ok = false;
- if (!u->fingerprint.empty() && target->nc->FindCert(u->fingerprint))
+ if (!na && u->Account())
+ ok = true;
+ else if (!u->fingerprint.empty() && target->nc->FindCert(u->fingerprint))
ok = true;
else if (!pass.empty())
{
diff --git a/modules/extra/db_mysql.cpp b/modules/extra/db_mysql.cpp
index 9662d75a6..9a2c44d47 100644
--- a/modules/extra/db_mysql.cpp
+++ b/modules/extra/db_mysql.cpp
@@ -879,17 +879,17 @@ class DBMySQL : public Module
void OnAccessAdd(ChannelInfo *ci, User *u, ChanAccess *access)
{
- this->RunQuery("INSERT INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES (" + stringify(access->level) + ", '" + this->Escape(access->mask) + "', '" + this->Escape(ci->name) + "', " + stringify(Anope::CurTime) + ", '" + this->Escape(u->nick) + "')");
+ this->RunQuery("INSERT INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES (" + stringify(access->level) + ", '" + this->Escape(access->GetMask()) + "', '" + this->Escape(ci->name) + "', " + stringify(Anope::CurTime) + ", '" + this->Escape(u->nick) + "')");
}
void OnAccessDel(ChannelInfo *ci, User *u, ChanAccess *access)
{
- this->RunQuery("DELETE FROM `anope_cs_access` WHERE `display` = '" + this->Escape(access->mask) + "' AND `channel` = '" + this->Escape(ci->name) + "'");
+ this->RunQuery("DELETE FROM `anope_cs_access` WHERE `display` = '" + this->Escape(access->GetMask()) + "' AND `channel` = '" + this->Escape(ci->name) + "'");
}
void OnAccessChange(ChannelInfo *ci, User *u, ChanAccess *access)
{
- this->RunQuery("INSERT INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES (" + stringify(access->level) + ", '" + this->Escape(access->mask) + "', '" + this->Escape(ci->name) + "', " + stringify(Anope::CurTime) + ", '" + this->Escape(u->nick) + "') ON DUPLICATE KEY UPDATE level=VALUES(level), display=VALUES(display), channel=VALUES(channel), last_seen=VALUES(last_seen), creator=VALUES(creator)");
+ this->RunQuery("INSERT INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES (" + stringify(access->level) + ", '" + this->Escape(access->GetMask()) + "', '" + this->Escape(ci->name) + "', " + stringify(Anope::CurTime) + ", '" + this->Escape(u->nick) + "') ON DUPLICATE KEY UPDATE level=VALUES(level), display=VALUES(display), channel=VALUES(channel), last_seen=VALUES(last_seen), creator=VALUES(creator)");
}
void OnAccessClear(ChannelInfo *ci, User *u)
@@ -1248,7 +1248,7 @@ static void SaveDatabases()
{
ChanAccess *access = ci->GetAccess(j);
- me->RunQuery(Anope::string("INSERT INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES(") + stringify(access->level) + ", '" + me->Escape(access->mask) + "', '" + me->Escape(ci->name) + "', " + stringify(access->last_seen) + ", '" + me->Escape(access->creator) + "') ON DUPLICATE KEY UPDATE level=VALUES(level), last_seen=VALUES(last_seen), creator=VALUES(creator)");
+ me->RunQuery(Anope::string("INSERT INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES(") + stringify(access->level) + ", '" + me->Escape(access->GetMask()) + "', '" + me->Escape(ci->name) + "', " + stringify(access->last_seen) + ", '" + me->Escape(access->creator) + "') ON DUPLICATE KEY UPDATE level=VALUES(level), last_seen=VALUES(last_seen), creator=VALUES(creator)");
}
for (unsigned j = 0, end = ci->GetAkickCount(); j < end; ++j)
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index b1e7ccdbd..9d0a95059 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -12,8 +12,26 @@
#include "services.h"
#include "modules.h"
-// Awesome channel access hack for superadmin and founder
-static ChanAccess dummy_access;
+ChanAccess::ChanAccess(const Anope::string &umask)
+{
+ NickAlias *na = findnick(umask);
+ if (na != NULL)
+ this->nc = na->nc;
+ else
+ {
+ this->nc = NULL;
+ this->mask = umask;
+ if (ircdproto->IsNickValid(this->mask))
+ this->mask += "!*@*";
+ }
+}
+
+const Anope::string &ChanAccess::GetMask()
+{
+ if (this->nc != NULL)
+ return this->nc->display;
+ return this->mask;
+}
/** Default constructor
* @param chname The channel name
@@ -90,7 +108,7 @@ ChannelInfo::ChannelInfo(ChannelInfo *ci) : Flags<ChannelInfoFlag, CI_END>(Chann
for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
{
ChanAccess *taccess = ci->GetAccess(i);
- this->AddAccess(taccess->mask, taccess->level, taccess->creator, taccess->last_seen);
+ this->AddAccess(taccess->GetMask(), taccess->level, taccess->creator, taccess->last_seen);
}
for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
{
@@ -159,9 +177,7 @@ ChannelInfo::~ChannelInfo()
ChanAccess *ChannelInfo::AddAccess(const Anope::string &mask, int16 level, const Anope::string &creator, int32 last_seen)
{
- ChanAccess *new_access = new ChanAccess();
- new_access->mask = mask;
- new_access->nc = findcore(mask);
+ ChanAccess *new_access = new ChanAccess(mask);
new_access->level = level;
new_access->last_seen = last_seen;
if (!creator.empty())
@@ -205,9 +221,9 @@ ChanAccess *ChannelInfo::GetAccess(User *u, int16 level)
if (u->isSuperAdmin || IsFounder(u, this))
{
+ static ChanAccess dummy_access("");
+ new(&dummy_access) ChanAccess(u->nick + "!*@*");
dummy_access.level = u->isSuperAdmin ? ACCESS_SUPERADMIN : ACCESS_FOUNDER;
- dummy_access.mask = u->nick + "!*@*";
- dummy_access.nc = NULL;
dummy_access.last_seen = Anope::CurTime;
return &dummy_access;
}
@@ -223,7 +239,7 @@ ChanAccess *ChannelInfo::GetAccess(User *u, int16 level)
if (level && level != taccess->level)
continue;
/* Access entry is a mask and we match it */
- else if (!taccess->nc && (Anope::Match(u->nick, taccess->mask) || Anope::Match(u->GetDisplayedMask(), taccess->mask)))
+ else if (!taccess->nc && (Anope::Match(u->nick, taccess->GetMask()) || Anope::Match(u->GetDisplayedMask(), taccess->GetMask())))
;
/* Access entry is a nick core and we are identified for that account */
else if (taccess->nc && (u->IsIdentified() || (u->IsRecognized() && !this->HasFlag(CI_SECURE))) && u->Account() == taccess->nc)
@@ -251,9 +267,9 @@ ChanAccess *ChannelInfo::GetAccess(NickCore *nc, int16 level)
{
if (nc == this->founder)
{
+ static ChanAccess dummy_access("");
+ new(&dummy_access) ChanAccess(nc->display);
dummy_access.level = ACCESS_FOUNDER;
- dummy_access.mask = nc->display;
- dummy_access.nc = nc;
dummy_access.last_seen = Anope::CurTime;
return &dummy_access;
}
@@ -279,7 +295,12 @@ ChanAccess *ChannelInfo::GetAccess(NickCore *nc, int16 level)
ChanAccess *ChannelInfo::GetAccess(const Anope::string &mask, int16 level, bool wildcard)
{
for (unsigned i = 0, end = this->access.size(); i < end; ++i)
- if (wildcard ? Anope::Match(this->access[i]->mask, mask) : this->access[i]->mask.equals_ci(mask))
+ if (this->access[i]->nc != NULL)
+ {
+ if (wildcard ? Anope::Match(this->access[i]->nc->display, mask) : this->access[i]->nc->display.equals_ci(mask))
+ return this->access[i];
+ }
+ else if (wildcard ? Anope::Match(this->access[i]->GetMask(), mask) : this->access[i]->GetMask().equals_ci(mask))
return this->access[i];
return NULL;
}