diff options
author | Sadie Powell <sadie@witchery.services> | 2025-02-12 15:39:41 +0000 |
---|---|---|
committer | Sadie Powell <sadie@witchery.services> | 2025-02-12 15:39:41 +0000 |
commit | 3e986b215e45c2fa15d1b07da8fef19e3560e45b (patch) | |
tree | ef0f6e3fef01987dc53596b14d7ede5a65834439 | |
parent | 8486962fefb85c810f77a42e15e51d68af93c6ef (diff) |
Add extra protections to avoid rebooting the wrong network.
-rw-r--r-- | data/operserv.example.conf | 12 | ||||
-rw-r--r-- | modules/operserv/os_shutdown.cpp | 36 |
2 files changed, 44 insertions, 4 deletions
diff --git a/data/operserv.example.conf b/data/operserv.example.conf index a320bd824..5b4447c48 100644 --- a/data/operserv.example.conf +++ b/data/operserv.example.conf @@ -649,7 +649,17 @@ command { service = "OperServ"; name = "SET"; command = "operserv/set"; permissi * * Used to quit, restart, or shutdown services. */ -module { name = "os_shutdown" } +module +{ + name = "os_shutdown" + + /* + * If enabled then server operators will be required to provide the network + * name to confirm that they are quitting, restarting, or shutting down the + * right server. + */ + requirename = yes +} command { service = "OperServ"; name = "QUIT"; command = "operserv/quit"; permission = "operserv/quit"; } command { service = "OperServ"; name = "RESTART"; command = "operserv/restart"; permission = "operserv/restart"; } command { service = "OperServ"; name = "SHUTDOWN"; command = "operserv/shutdown"; permission = "operserv/shutdown"; } diff --git a/modules/operserv/os_shutdown.cpp b/modules/operserv/os_shutdown.cpp index c220bac87..5ebdb2200 100644 --- a/modules/operserv/os_shutdown.cpp +++ b/modules/operserv/os_shutdown.cpp @@ -15,13 +15,23 @@ class CommandOSQuit final : public Command { public: - CommandOSQuit(Module *creator) : Command(creator, "operserv/quit", 0, 0) + CommandOSQuit(Module *creator) : Command(creator, "operserv/quit", 0, 1) { this->SetDesc(_("Terminate services WITHOUT saving")); + if (Config->GetModule(this->owner)->Get<bool>("requirename")) + this->SetSyntax(_("\037network-name\037")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { + const auto requirename = Config->GetModule(this->owner)->Get<bool>("requirename"); + const auto networkname = Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"); + if (requirename && (params.empty() || !params[0].equals_cs(networkname))) + { + OnSyntaxError(source, source.command); + return; + } + Log(LOG_ADMIN, source, this); Anope::QuitReason = source.command + " command received from " + source.GetNick(); Anope::Quitting = true; @@ -44,13 +54,23 @@ class CommandOSRestart final : public Command { public: - CommandOSRestart(Module *creator) : Command(creator, "operserv/restart", 0, 0) + CommandOSRestart(Module *creator) : Command(creator, "operserv/restart", 0, 1) { this->SetDesc(_("Save databases and restart services")); + if (Config->GetModule(this->owner)->Get<bool>("requirename")) + this->SetSyntax(_("\037network-name\037")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { + const auto requirename = Config->GetModule(this->owner)->Get<bool>("requirename"); + const auto networkname = Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"); + if (requirename && (params.empty() || !params[0].equals_cs(networkname))) + { + OnSyntaxError(source, source.command); + return; + } + Log(LOG_ADMIN, source, this); Anope::QuitReason = source.command + " command received from " + source.GetNick(); Anope::Quitting = Anope::Restarting = true; @@ -71,13 +91,23 @@ class CommandOSShutdown final : public Command { public: - CommandOSShutdown(Module *creator) : Command(creator, "operserv/shutdown", 0, 0) + CommandOSShutdown(Module *creator) : Command(creator, "operserv/shutdown", 0, 1) { this->SetDesc(_("Terminate services with save")); + if (Config->GetModule(this->owner)->Get<bool>("requirename")) + this->SetSyntax(_("\037network-name\037")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { + const auto requirename = Config->GetModule(this->owner)->Get<bool>("requirename"); + const auto networkname = Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"); + if (requirename && (params.empty() || !params[0].equals_cs(networkname))) + { + OnSyntaxError(source, source.command); + return; + } + Log(LOG_ADMIN, source, this); Anope::QuitReason = source.command + " command received from " + source.GetNick(); Anope::Quitting = true; |