summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2014-05-14 19:10:23 -0400
committerAdam <Adam@anope.org>2014-05-14 19:10:23 -0400
commitdf321a118e7dd44dcd3a389f8ee75e9ff915b55e (patch)
treef77aa4b3a73884c4a095df12be692292c8694bc0
parent1931fcf0e5ffe34005d134e49c55d1b6239d1a6c (diff)
Fix access lists showing the wrong mask if the display nick for a group
expires but the group still exists. This can cause access entries for nicks to not be deleted whenever the nicks are deleted.
-rw-r--r--include/access.h11
-rw-r--r--modules/commands/cs_access.cpp31
-rw-r--r--modules/commands/cs_clone.cpp9
-rw-r--r--modules/commands/cs_flags.cpp15
-rw-r--r--modules/commands/cs_seen.cpp2
-rw-r--r--modules/commands/cs_status.cpp2
-rw-r--r--modules/commands/cs_xop.cpp23
-rw-r--r--modules/database/db_old.cpp2
-rw-r--r--modules/pseudoclients/chanserv.cpp9
-rw-r--r--modules/webcpanel/pages/chanserv/access.cpp9
-rw-r--r--src/access.cpp53
-rw-r--r--src/regchannel.cpp16
12 files changed, 106 insertions, 76 deletions
diff --git a/include/access.h b/include/access.h
index 57229abab..323dc814d 100644
--- a/include/access.h
+++ b/include/access.h
@@ -74,6 +74,10 @@ class CoreExport AccessProvider : public Service
/* Represents one entry of an access list on a channel. */
class CoreExport ChanAccess : public Serializable
{
+ Anope::string mask;
+ /* account this access entry is for, if any */
+ Serialize::Reference<NickCore> nc;
+
public:
typedef std::multimap<const ChanAccess *, const ChanAccess *> Set;
/* shows the 'path' taken to determine if an access entry matches a user
@@ -86,9 +90,6 @@ class CoreExport ChanAccess : public Serializable
AccessProvider *provider;
/* Channel this access entry is on */
Serialize::Reference<ChannelInfo> ci;
- /* account this access entry is for, if any */
- Serialize::Reference<NickCore> nc;
- Anope::string mask;
Anope::string creator;
time_t last_seen;
time_t created;
@@ -96,6 +97,10 @@ class CoreExport ChanAccess : public Serializable
ChanAccess(AccessProvider *p);
virtual ~ChanAccess();
+ void SetMask(const Anope::string &mask, ChannelInfo *ci);
+ const Anope::string &Mask() const;
+ NickCore *GetAccount() const;
+
void Serialize(Serialize::Data &data) const anope_override;
static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp
index b4f682c66..d5f934862 100644
--- a/modules/commands/cs_access.cpp
+++ b/modules/commands/cs_access.cpp
@@ -180,7 +180,7 @@ class CommandCSAccess : public Command
for (unsigned i = ci->GetAccessCount(); i > 0; --i)
{
const ChanAccess *access = ci->GetAccess(i - 1);
- if (mask.equals_ci(access->mask))
+ if (mask.equals_ci(access->Mask()))
{
/* Don't allow lowering from a level >= u_level */
if ((!highest || *access >= *highest) && !u_access.founder && !source.HasPriv("chanserv/access/modify"))
@@ -204,8 +204,7 @@ class CommandCSAccess : public Command
if (!provider)
return;
AccessChanAccess *access = anope_dynamic_static_cast<AccessChanAccess *>(provider->Create());
- access->ci = ci;
- access->mask = mask;
+ access->SetMask(mask, ci);
access->creator = source.GetNick();
access->level = level;
access->last_seen = 0;
@@ -216,9 +215,9 @@ class CommandCSAccess : public Command
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask << " with level " << level;
if (p != NULL)
- source.Reply(_("\002%s\002 added to %s access list at privilege %s (level %d)"), access->mask.c_str(), ci->name.c_str(), p->name.c_str(), level);
+ source.Reply(_("\002%s\002 added to %s access list at privilege %s (level %d)"), access->Mask().c_str(), ci->name.c_str(), p->name.c_str(), level);
else
- 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->Mask().c_str(), ci->name.c_str(), level);
}
void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
@@ -284,7 +283,7 @@ class CommandCSAccess : public Command
AccessGroup ag = source.AccessFor(ci);
const ChanAccess *u_highest = ag.Highest();
- if ((!u_highest || *u_highest <= *access) && !ag.founder && !this->override && !access->mask.equals_ci(source.nc->display))
+ if ((!u_highest || *u_highest <= *access) && !ag.founder && !this->override && access->GetAccount() != source.nc)
{
denied = true;
return;
@@ -292,9 +291,9 @@ class CommandCSAccess : public Command
++deleted;
if (!Nicks.empty())
- Nicks += ", " + access->mask;
+ Nicks += ", " + access->Mask();
else
- Nicks = access->mask;
+ Nicks = access->Mask();
ci->EraseAccess(Number - 1);
@@ -313,15 +312,15 @@ class CommandCSAccess : public Command
for (unsigned i = ci->GetAccessCount(); i > 0; --i)
{
ChanAccess *access = ci->GetAccess(i - 1);
- if (mask.equals_ci(access->mask))
+ if (mask.equals_ci(access->Mask()))
{
- if (!access->mask.equals_ci(source.nc->display) && !u_access.founder && (!highest || *highest <= *access) && !source.HasPriv("chanserv/access/modify"))
+ if (access->GetAccount() != source.nc && !u_access.founder && (!highest || *highest <= *access) && !source.HasPriv("chanserv/access/modify"))
source.Reply(ACCESS_DENIED);
else
{
- source.Reply(_("\002%s\002 deleted from %s access list."), access->mask.c_str(), ci->name.c_str());
- bool override = !u_access.founder && !u_access.HasPriv("ACCESS_CHANGE") && !access->mask.equals_ci(source.nc->display);
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << access->mask;
+ source.Reply(_("\002%s\002 deleted from %s access list."), access->Mask().c_str(), ci->name.c_str());
+ bool override = !u_access.founder && !u_access.HasPriv("ACCESS_CHANGE") && access->GetAccount() != source.nc;
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << access->Mask();
ci->EraseAccess(i - 1);
FOREACH_MOD(OnAccessDel, (ci, source, access));
@@ -381,7 +380,7 @@ class CommandCSAccess : public Command
ListFormatter::ListEntry entry;
entry["Number"] = stringify(number);
entry["Level"] = access->AccessSerialize();
- entry["Mask"] = access->mask;
+ entry["Mask"] = access->Mask();
entry["By"] = access->creator;
entry["Last seen"] = timebuf;
this->list.AddEntry(entry);
@@ -396,7 +395,7 @@ class CommandCSAccess : public Command
{
const ChanAccess *access = ci->GetAccess(i);
- if (!nick.empty() && !Anope::Match(access->mask, nick))
+ if (!nick.empty() && !Anope::Match(access->Mask(), nick))
continue;
Anope::string timebuf;
@@ -418,7 +417,7 @@ class CommandCSAccess : public Command
ListFormatter::ListEntry entry;
entry["Number"] = stringify(i + 1);
entry["Level"] = access->AccessSerialize();
- entry["Mask"] = access->mask;
+ entry["Mask"] = access->Mask();
entry["By"] = access->creator;
entry["Last seen"] = timebuf;
list.AddEntry(entry);
diff --git a/modules/commands/cs_clone.cpp b/modules/commands/cs_clone.cpp
index e93029466..8365091cf 100644
--- a/modules/commands/cs_clone.cpp
+++ b/modules/commands/cs_clone.cpp
@@ -111,7 +111,7 @@ public:
unsigned count = 0;
for (unsigned i = 0; i < target_ci->GetAccessCount(); ++i)
- masks.insert(target_ci->GetAccess(i)->mask);
+ masks.insert(target_ci->GetAccess(i)->Mask());
for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
{
@@ -121,13 +121,12 @@ public:
if (access_max && target_ci->GetDeepAccessCount() >= access_max)
break;
- if (masks.count(taccess->mask))
+ if (masks.count(taccess->Mask()))
continue;
- masks.insert(taccess->mask);
+ masks.insert(taccess->Mask());
ChanAccess *newaccess = provider->Create();
- newaccess->ci = target_ci;
- newaccess->mask = taccess->mask;
+ newaccess->SetMask(taccess->Mask(), target_ci);
newaccess->creator = taccess->creator;
newaccess->last_seen = taccess->last_seen;
newaccess->created = taccess->created;
diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp
index 01314e2d3..e3f3da978 100644
--- a/modules/commands/cs_flags.cpp
+++ b/modules/commands/cs_flags.cpp
@@ -142,7 +142,7 @@ class CommandCSFlags : public Command
for (current_idx = ci->GetAccessCount(); current_idx > 0; --current_idx)
{
ChanAccess *access = ci->GetAccess(current_idx - 1);
- if (mask.equals_ci(access->mask))
+ if (mask.equals_ci(access->Mask()))
{
// Flags allows removing others that have the same access as you,
// but no other access system does.
@@ -260,8 +260,7 @@ class CommandCSFlags : public Command
if (!provider)
return;
FlagsChanAccess *access = anope_dynamic_static_cast<FlagsChanAccess *>(provider->Create());
- access->ci = ci;
- access->mask = mask;
+ access->SetMask(mask, ci);
access->creator = source.GetNick();
access->last_seen = current ? current->last_seen : 0;
access->created = Anope::CurTime;
@@ -278,12 +277,12 @@ class CommandCSFlags : public Command
if (p != NULL)
{
if (add)
- source.Reply(_("Privilege \002%s\002 added to \002%s\002 on \002%s\002, new flags are +\002%s\002"), p->name.c_str(), access->mask.c_str(), ci->name.c_str(), access->AccessSerialize().c_str());
+ source.Reply(_("Privilege \002%s\002 added to \002%s\002 on \002%s\002, new flags are +\002%s\002"), p->name.c_str(), access->Mask().c_str(), ci->name.c_str(), access->AccessSerialize().c_str());
else
- source.Reply(_("Privilege \002%s\002 removed from \002%s\002 on \002%s\002, new flags are +\002%s\002"), p->name.c_str(), access->mask.c_str(), ci->name.c_str(), access->AccessSerialize().c_str());
+ source.Reply(_("Privilege \002%s\002 removed from \002%s\002 on \002%s\002, new flags are +\002%s\002"), p->name.c_str(), access->Mask().c_str(), ci->name.c_str(), access->AccessSerialize().c_str());
}
else
- source.Reply(_("Flags for \002%s\002 on %s set to +\002%s\002"), access->mask.c_str(), ci->name.c_str(), access->AccessSerialize().c_str());
+ source.Reply(_("Flags for \002%s\002 on %s set to +\002%s\002"), access->Mask().c_str(), ci->name.c_str(), access->AccessSerialize().c_str());
}
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
@@ -317,14 +316,14 @@ class CommandCSFlags : public Command
if (pass == false)
continue;
}
- else if (!Anope::Match(access->mask, arg))
+ else if (!Anope::Match(access->Mask(), arg))
continue;
}
ListFormatter::ListEntry entry;
++count;
entry["Number"] = stringify(i + 1);
- entry["Mask"] = access->mask;
+ entry["Mask"] = access->Mask();
entry["Flags"] = flags;
entry["Creator"] = access->creator;
entry["Created"] = Anope::strftime(access->created, source.nc, true);
diff --git a/modules/commands/cs_seen.cpp b/modules/commands/cs_seen.cpp
index c6dbec9a9..923edb361 100644
--- a/modules/commands/cs_seen.cpp
+++ b/modules/commands/cs_seen.cpp
@@ -241,7 +241,7 @@ class CommandSeen : public Command
{
ChanAccess *a = ag[i];
- if (*a->nc == na->nc && a->last_seen > last)
+ if (a->GetAccount() == na->nc && a->last_seen > last)
last = a->last_seen;
}
diff --git a/modules/commands/cs_status.cpp b/modules/commands/cs_status.cpp
index 2ecaf8e9f..115085e83 100644
--- a/modules/commands/cs_status.cpp
+++ b/modules/commands/cs_status.cpp
@@ -61,7 +61,7 @@ public:
{
ChanAccess *acc = ag[i];
- source.Reply(_("\002%s\002 matches access entry %s, which has privilege %s."), nick.c_str(), acc->mask.c_str(), acc->AccessSerialize().c_str());
+ source.Reply(_("\002%s\002 matches access entry %s, which has privilege %s."), nick.c_str(), acc->Mask().c_str(), acc->AccessSerialize().c_str());
}
}
diff --git a/modules/commands/cs_xop.cpp b/modules/commands/cs_xop.cpp
index 72b1e0def..4c48dcc01 100644
--- a/modules/commands/cs_xop.cpp
+++ b/modules/commands/cs_xop.cpp
@@ -182,7 +182,7 @@ class CommandCSXOP : public Command
{
const ChanAccess *a = ci->GetAccess(i);
- if (a->mask.equals_ci(mask))
+ if (a->Mask().equals_ci(mask))
{
if ((!highest || *a >= *highest) && !access.founder && !source.HasPriv("chanserv/access/modify"))
{
@@ -206,8 +206,7 @@ class CommandCSXOP : public Command
if (!provider)
return;
XOPChanAccess *acc = anope_dynamic_static_cast<XOPChanAccess *>(provider->Create());
- acc->ci = ci;
- acc->mask = mask;
+ acc->SetMask(mask, ci);
acc->creator = source.GetNick();
acc->type = source.command.upper();
acc->last_seen = 0;
@@ -217,7 +216,7 @@ class CommandCSXOP : public Command
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask;
FOREACH_MOD(OnAccessAdd, (ci, source, acc));
- source.Reply(_("\002%s\002 added to %s %s list."), acc->mask.c_str(), ci->name.c_str(), source.command.c_str());
+ source.Reply(_("\002%s\002 added to %s %s list."), acc->Mask().c_str(), ci->name.c_str(), source.command.c_str());
}
void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
@@ -320,9 +319,9 @@ class CommandCSXOP : public Command
++deleted;
if (!nicks.empty())
- nicks += ", " + caccess->mask;
+ nicks += ", " + caccess->Mask();
else
- nicks = caccess->mask;
+ nicks = caccess->Mask();
ci->EraseAccess(number - 1);
FOREACH_MOD(OnAccessDel, (ci, source, caccess));
@@ -341,11 +340,11 @@ class CommandCSXOP : public Command
if (a->provider->name != "access/xop" || source.command.upper() != a->AccessSerialize())
continue;
- if (a->mask.equals_ci(mask))
+ if (a->Mask().equals_ci(mask))
{
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << a->mask;
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << a->Mask();
- source.Reply(_("\002%s\002 deleted from %s %s list."), a->mask.c_str(), ci->name.c_str(), source.command.c_str());
+ source.Reply(_("\002%s\002 deleted from %s %s list."), a->Mask().c_str(), ci->name.c_str(), source.command.c_str());
ci->EraseAccess(i);
FOREACH_MOD(OnAccessDel, (ci, source, a));
@@ -405,7 +404,7 @@ class CommandCSXOP : public Command
ListFormatter::ListEntry entry;
entry["Number"] = stringify(Number);
- entry["Mask"] = a->mask;
+ entry["Mask"] = a->Mask();
this->list.AddEntry(entry);
}
} nl_list(list, ci, nick, source);
@@ -419,12 +418,12 @@ class CommandCSXOP : public Command
if (a->provider->name != "access/xop" || source.command.upper() != a->AccessSerialize())
continue;
- else if (!nick.empty() && !Anope::Match(a->mask, nick))
+ else if (!nick.empty() && !Anope::Match(a->Mask(), nick))
continue;
ListFormatter::ListEntry entry;
entry["Number"] = stringify(i + 1);
- entry["Mask"] = a->mask;
+ entry["Mask"] = a->Mask();
list.AddEntry(entry);
}
}
diff --git a/modules/database/db_old.cpp b/modules/database/db_old.cpp
index b49a6c46e..b73afbc41 100644
--- a/modules/database/db_old.cpp
+++ b/modules/database/db_old.cpp
@@ -898,7 +898,7 @@ static void LoadChannels()
Anope::string mask;
READ(read_string(mask, f));
if (access)
- access->mask = mask;
+ access->SetMask(mask, ci);
READ(read_int32(&tmp32, f));
if (access)
diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp
index 250296f55..3640a006c 100644
--- a/modules/pseudoclients/chanserv.cpp
+++ b/modules/pseudoclients/chanserv.cpp
@@ -154,7 +154,7 @@ class ChanServCore : public Module, public ChanServService
for (unsigned j = 0; j < ci->GetAccessCount(); ++j)
{
const ChanAccess *ca = ci->GetAccess(j);
- const NickCore *anc = NickCore::Find(ca->mask);
+ NickCore *anc = ca->GetAccount();
if (!anc || (!anc->IsServicesOper() && max_reg && anc->channelcount >= max_reg) || (anc == nc))
continue;
@@ -162,7 +162,7 @@ class ChanServCore : public Module, public ChanServService
highest = ca;
}
if (highest)
- newowner = NickCore::Find(highest->mask);
+ newowner = highest->GetAccount();
}
if (newowner)
@@ -186,9 +186,8 @@ class ChanServCore : public Module, public ChanServService
for (unsigned j = 0; j < ci->GetAccessCount(); ++j)
{
const ChanAccess *ca = ci->GetAccess(j);
- const NickCore *anc = NickCore::Find(ca->mask);
- if (anc && anc == nc)
+ if (ca->GetAccount() == nc)
{
delete ci->EraseAccess(j);
break;
@@ -224,7 +223,7 @@ class ChanServCore : public Module, public ChanServService
{
ChanAccess *a = c->GetAccess(j);
- if (a->mask.equals_ci(ci->name))
+ if (a->Mask().equals_ci(ci->name))
{
delete a;
break;
diff --git a/modules/webcpanel/pages/chanserv/access.cpp b/modules/webcpanel/pages/chanserv/access.cpp
index d87613ed7..39750a283 100644
--- a/modules/webcpanel/pages/chanserv/access.cpp
+++ b/modules/webcpanel/pages/chanserv/access.cpp
@@ -75,7 +75,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
{
ChanAccess *acc = ci->GetAccess(i);
- if (acc->mask == message.post_data["mask"])
+ if (acc->Mask() == message.post_data["mask"])
{
if ((!highest || *acc >= *highest) && !u_access.founder && !has_priv)
{
@@ -95,8 +95,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
else if (!denied)
{
ChanAccess *new_acc = a->Create();
- new_acc->ci = ci;
- new_acc->mask = message.post_data["mask"];
+ new_acc->SetMask(message.post_data["mask"], ci);
new_acc->creator = na->nc->display;
try
{
@@ -123,7 +122,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
else
{
ci->AddAccess(new_acc);
- replacements["MESSAGES"] = "Access for " + new_acc->mask + " set to " + new_acc->AccessSerialize();
+ replacements["MESSAGES"] = "Access for " + new_acc->Mask() + " set to " + new_acc->AccessSerialize();
}
}
}
@@ -138,7 +137,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
{
ChanAccess *access = ci->GetAccess(i);
- replacements["MASKS"] = HTTPUtils::Escape(access->mask);
+ replacements["MASKS"] = HTTPUtils::Escape(access->Mask());
replacements["ACCESSES"] = HTTPUtils::Escape(access->AccessSerialize());
replacements["CREATORS"] = HTTPUtils::Escape(access->creator);
}
diff --git a/src/access.cpp b/src/access.cpp
index 1b90bb59f..74ff018b9 100644
--- a/src/access.cpp
+++ b/src/access.cpp
@@ -151,9 +151,8 @@ ChanAccess::~ChanAccess()
if (it != this->ci->access->end())
this->ci->access->erase(it);
- const NickAlias *na = NickAlias::Find(this->mask);
- if (na != NULL)
- na->nc->RemoveChannelReference(this->ci);
+ if (nc != NULL)
+ nc->RemoveChannelReference(this->ci);
else
{
ChannelInfo *c = ChannelInfo::Find(this->mask);
@@ -163,6 +162,50 @@ ChanAccess::~ChanAccess()
}
}
+void ChanAccess::SetMask(const Anope::string &m, ChannelInfo *c)
+{
+ if (nc != NULL)
+ nc->RemoveChannelReference(this->ci);
+ else if (!this->mask.empty())
+ {
+ ChannelInfo *targc = ChannelInfo::Find(this->mask);
+ if (targc)
+ targc->RemoveChannelReference(this->ci->name);
+ }
+
+ ci = c;
+ mask.clear();
+ nc = NULL;
+
+ const NickAlias *na = NickAlias::Find(m);
+ if (na != NULL)
+ {
+ nc = na->nc;
+ nc->AddChannelReference(ci);
+ }
+ else
+ {
+ mask = m;
+
+ ChannelInfo *targci = ChannelInfo::Find(mask);
+ if (targci != NULL)
+ targci->AddChannelReference(ci->name);
+ }
+}
+
+const Anope::string &ChanAccess::Mask() const
+{
+ if (nc)
+ return nc->display;
+ else
+ return mask;
+}
+
+NickCore *ChanAccess::GetAccount() const
+{
+ return nc;
+}
+
void ChanAccess::Serialize(Serialize::Data &data) const
{
data["provider"] << this->provider->name;
@@ -192,7 +235,9 @@ Serializable* ChanAccess::Unserialize(Serializable *obj, Serialize::Data &data)
else
access = aprovider->Create();
access->ci = ci;
- data["mask"] >> access->mask;
+ Anope::string m;
+ data["mask"] >> m;
+ access->SetMask(m, ci);
data["creator"] >> access->creator;
data["last_seen"] >> access->last_seen;
data["created"] >> access->created;
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index 0228196a0..7e0ce300c 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -143,8 +143,7 @@ ChannelInfo::ChannelInfo(const ChannelInfo &ci) : Serializable("ChannelInfo"),
AccessProvider *provider = taccess->provider;
ChanAccess *newaccess = provider->Create();
- newaccess->ci = this;
- newaccess->mask = taccess->mask;
+ newaccess->SetMask(taccess->Mask(), this);
newaccess->creator = taccess->creator;
newaccess->last_seen = taccess->last_seen;
newaccess->created = taccess->created;
@@ -399,19 +398,6 @@ BotInfo *ChannelInfo::WhoSends() const
void ChannelInfo::AddAccess(ChanAccess *taccess)
{
this->access->push_back(taccess);
-
- const NickAlias *na = NickAlias::Find(taccess->mask);
- if (na != NULL)
- {
- na->nc->AddChannelReference(this);
- taccess->nc = na->nc;
- }
- else
- {
- ChannelInfo *ci = ChannelInfo::Find(taccess->mask);
- if (ci != NULL)
- ci->AddChannelReference(this->name);
- }
}
ChanAccess *ChannelInfo::GetAccess(unsigned index) const