From 5afb3097a54f82bfdb1734561f49bd3481176e5a Mon Sep 17 00:00:00 2001 From: cflakes Date: Sun, 28 Mar 2010 20:37:48 +0000 Subject: [PATCH] Add LoadModule, UnLoadModule, ListMods commands to the admin module. This means that admins can now load user modules for other users. Patch by Nirjen. Thanks, great job! git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1845 726aef4b-f618-498e-8847-2d620e286838 --- AUTHORS | 1 + modules/admin.cpp | 138 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 120 insertions(+), 19 deletions(-) diff --git a/AUTHORS b/AUTHORS index 86fc36b3..a04be20d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -24,3 +24,4 @@ Ingmar "KiNgMaR" Runge Michael "Svedrin" Ziegler Robert Lacroix (http://www.robertlacroix.com) zynox +Martin "Nirjen" Martimeo diff --git a/modules/admin.cpp b/modules/admin.cpp index 1dffb126..63f11fb6 100644 --- a/modules/admin.cpp +++ b/modules/admin.cpp @@ -35,15 +35,18 @@ class CAdminMod : public CModule { CmdTable.AddColumn("Arguments"); CmdTable.AddColumn("Description"); static const char* help[][3] = { - {"Get", "variable [username]", "Prints the variable's value for the given or current user"}, - {"Set", "variable username value", "Sets the variable's value for the given user (use $me for the current user)"}, - {"GetChan", "variable [username] chan", "Prints the variable's value for the given channel"}, - {"SetChan", "variable username chan value", "Sets the variable's value for the given channel"}, - {"ListUsers", "", "Lists users"}, - {"AddUser", "username password [ircserver]", "Adds a new user"}, - {"DelUser", "username", "Deletes a user"}, - {"CloneUser", "oldusername newusername", "Clones a user"}, - {"AddServer", "[username] server", "Adds a new IRC server for the given or current user"} + {"Get", "variable [username]", "Prints the variable's value for the given or current user"}, + {"Set", "variable username value", "Sets the variable's value for the given user (use $me for the current user)"}, + {"GetChan", "variable [username] chan", "Prints the variable's value for the given channel"}, + {"SetChan", "variable username chan value", "Sets the variable's value for the given channel"}, + {"ListUsers", "", "Lists users"}, + {"AddUser", "username password [ircserver]", "Adds a new user"}, + {"DelUser", "username", "Deletes a user"}, + {"CloneUser", "oldusername newusername", "Clones a user"}, + {"AddServer", "[username] server", "Adds a new IRC server for the given or current user"}, + {"LoadModule", "username modulename", "Loads a Module for a user"}, + {"UnLoadModule", "username modulename", "Removes a Module of a user"}, + {"ListMods", "username", "Get the list of modules for a user"} }; for (unsigned int i = 0; i != ARRAY_SIZE(help); ++i) { CmdTable.AddRow(); @@ -579,7 +582,101 @@ class CAdminMod : public CModule { user->AddServer(server); PutModule("Added IRC Server: " + server); } + + void LoadModuleForUser(const CString& sLine) { + CString sUsername = sLine.Token(1); + CString sModName = sLine.Token(2); + CString sArgs = sLine.Token(3, true); + CString sModRet; + if (!m_pUser->IsAdmin()) { + PutModule("Error: You need to have admin rights to modify users!"); + return; + } + + if (sModName.empty()) { + PutModule("Usage: loadmodule "); + return; + } + + CUser* pUser = GetUser(sUsername); + if (!pUser) + return; + + CModule *pMod = (pUser)->GetModules().FindModule(sModName); + if (!pMod) { + if (!(pUser)->GetModules().LoadModule(sModName, sArgs, pUser, sModRet, false)) { + PutModule("Unable to load module [" + sModName + "] [" + sModRet + "]"); + } else { + PutModule("Loaded module [" + sModName + "]"); + } + } else if (pMod->GetArgs() != sArgs) { + if (!(pUser)->GetModules().ReloadModule(sModName, sArgs, pUser, sModRet)) { + PutModule("Unable to reload module [" + sModName + "] [" + sModRet + "]"); + } else { + PutModule("Reloaded module [" + sModName + "]"); + } + } else { + PutModule("Unable to load module [" + sModName + "] because it is already loaded"); + } + } + + void UnLoadModuleForUser(const CString& sLine) { + CString sUsername = sLine.Token(1); + CString sModName = sLine.Token(2); + CString sArgs = sLine.Token(3, true); + CString sModRet; + + if (!m_pUser->IsAdmin()) { + PutModule("Error: You need to have admin rights to modify users!"); + return; + } + + if (sModName.empty()) { + PutModule("Usage: loadmodule "); + return; + } + + CUser* pUser = GetUser(sUsername); + if (!pUser) + return; + + if (!(pUser)->GetModules().UnloadModule(sModName, sModRet)) { + PutModule("Unable to unload module [" + sModName + "] [" + sModRet + "]"); + } else { + PutModule("Unloaded module [" + sModName + "] [" + sModRet + "]"); + } + } + + void ListModuleForUser(const CString& sLine) { + CString sUsername = sLine.Token(1, true); + + CUser* pUser = GetUser(sUsername); + if (!pUser || (pUser != m_pUser && !m_pUser->IsAdmin())) { + PutModule("Usage: listmods "); + return; + } + + CModules& Modules = pUser->GetModules(); + + if (!Modules.size()) { + PutModule("This user has no modules loaded."); + } else { + PutModule("User modules:"); + CTable Table; + Table.AddColumn("Name"); + Table.AddColumn("Arguments"); + + for (unsigned int b = 0; b < Modules.size(); b++) { + Table.AddRow(); + Table.SetCell("Name", Modules[b]->GetModName()); + Table.SetCell("Arguments", Modules[b]->GetArgs()); + } + + PutModule(Table); + } + + } typedef void (CAdminMod::* fn)(const CString&); typedef std::map function_map; @@ -587,16 +684,19 @@ class CAdminMod : public CModule { public: MODCONSTRUCTOR(CAdminMod) { - fnmap_["help"] = &CAdminMod::PrintHelp; - fnmap_["get"] = &CAdminMod::Get; - fnmap_["set"] = &CAdminMod::Set; - fnmap_["getchan"] = &CAdminMod::GetChan; - fnmap_["setchan"] = &CAdminMod::SetChan; - fnmap_["listusers"] = &CAdminMod::ListUsers; - fnmap_["adduser"] = &CAdminMod::AddUser; - fnmap_["deluser"] = &CAdminMod::DelUser; - fnmap_["cloneuser"] = &CAdminMod::CloneUser; - fnmap_["addserver"] = &CAdminMod::AddServer; + fnmap_["help"] = &CAdminMod::PrintHelp; + fnmap_["get"] = &CAdminMod::Get; + fnmap_["set"] = &CAdminMod::Set; + fnmap_["getchan"] = &CAdminMod::GetChan; + fnmap_["setchan"] = &CAdminMod::SetChan; + fnmap_["listusers"] = &CAdminMod::ListUsers; + fnmap_["adduser"] = &CAdminMod::AddUser; + fnmap_["deluser"] = &CAdminMod::DelUser; + fnmap_["cloneuser"] = &CAdminMod::CloneUser; + fnmap_["addserver"] = &CAdminMod::AddServer; + fnmap_["loadmodule"] = &CAdminMod::LoadModuleForUser; + fnmap_["unloadmodule"] = &CAdminMod::UnLoadModuleForUser; + fnmap_["listmods"] = &CAdminMod::ListModuleForUser; } virtual ~CAdminMod() {}