diff options
author | Adam <Adam@anope.org> | 2014-05-14 19:10:23 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2014-05-14 19:10:23 -0400 |
commit | df321a118e7dd44dcd3a389f8ee75e9ff915b55e (patch) | |
tree | f77aa4b3a73884c4a095df12be692292c8694bc0 | |
parent | 1931fcf0e5ffe34005d134e49c55d1b6239d1a6c (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.h | 11 | ||||
-rw-r--r-- | modules/commands/cs_access.cpp | 31 | ||||
-rw-r--r-- | modules/commands/cs_clone.cpp | 9 | ||||
-rw-r--r-- | modules/commands/cs_flags.cpp | 15 | ||||
-rw-r--r-- | modules/commands/cs_seen.cpp | 2 | ||||
-rw-r--r-- | modules/commands/cs_status.cpp | 2 | ||||
-rw-r--r-- | modules/commands/cs_xop.cpp | 23 | ||||
-rw-r--r-- | modules/database/db_old.cpp | 2 | ||||
-rw-r--r-- | modules/pseudoclients/chanserv.cpp | 9 | ||||
-rw-r--r-- | modules/webcpanel/pages/chanserv/access.cpp | 9 | ||||
-rw-r--r-- | src/access.cpp | 53 | ||||
-rw-r--r-- | src/regchannel.cpp | 16 |
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> ¶ms) @@ -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> ¶ms) @@ -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> ¶ms) @@ -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 |