diff options
author | Adam <Adam@anope.org> | 2011-05-01 18:41:54 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2011-05-01 18:41:54 -0400 |
commit | 4a3c64291f683823a1f8977c00f57b57af577f03 (patch) | |
tree | 53129214f4d48bc3a661d7e1a83c60576758cb46 | |
parent | 036b3c9053d663b0714690db33161e2df9e76782 (diff) |
Fixed sometimes not removing nick masks from the access list when the group is dropped
-rw-r--r-- | include/language.h | 2 | ||||
-rw-r--r-- | include/regchannel.h | 38 | ||||
-rw-r--r-- | include/services.h | 40 | ||||
-rw-r--r-- | modules/core/cs_access.cpp | 26 | ||||
-rw-r--r-- | modules/core/cs_clone.cpp | 2 | ||||
-rw-r--r-- | modules/core/cs_xop.cpp | 16 | ||||
-rw-r--r-- | modules/core/db_plain.cpp | 2 | ||||
-rw-r--r-- | modules/core/ns_group.cpp | 4 | ||||
-rw-r--r-- | modules/extra/db_mysql.cpp | 8 | ||||
-rw-r--r-- | src/regchannel.cpp | 45 |
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; } |