diff options
Diffstat (limited to 'modules/commands/cs_flags.cpp')
-rw-r--r-- | modules/commands/cs_flags.cpp | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp index 0a93e6386..6c65a72cb 100644 --- a/modules/commands/cs_flags.cpp +++ b/modules/commands/cs_flags.cpp @@ -52,15 +52,21 @@ class FlagsChanAccess : public ChanAccess if (access->HasPriv(it->first)) buffer.insert(it->second); - return Anope::string(buffer.begin(), buffer.end()); + if (buffer.empty()) + return "(none)"; + else + return Anope::string(buffer.begin(), buffer.end()); } }; class FlagsAccessProvider : public AccessProvider { public: + static FlagsAccessProvider *ap; + FlagsAccessProvider(Module *o) : AccessProvider(o, "access/flags") { + ap = this; } ChanAccess *Create() anope_override @@ -68,6 +74,7 @@ class FlagsAccessProvider : public AccessProvider return new FlagsChanAccess(this); } }; +FlagsAccessProvider* FlagsAccessProvider::ap; class CommandCSFlags : public Command { @@ -83,6 +90,9 @@ class CommandCSFlags : public Command } AccessGroup u_access = source.AccessFor(ci); + const ChanAccess *highest = u_access.Highest(); + if (!highest) + return; if (IRCD->IsChannelValid(mask)) { @@ -135,6 +145,16 @@ class CommandCSFlags : public Command ChanAccess *access = ci->GetAccess(current_idx - 1); if (mask.equals_ci(access->mask)) { + // Flags allows removing others that have the same access as you, + // but no other access system does. + if (highest->provider != FlagsAccessProvider::ap) + // operator<= on the non-me entry! + if (*highest <= *access) + { + source.Reply(ACCESS_DENIED); + return; + } + current = access; Anope::string cur_flags = FlagsChanAccess::DetermineFlags(access); for (unsigned j = cur_flags.length(); j > 0; --j) |