#include "main.h" #include "User.h" #include "Nick.h" #include "Modules.h" #include "Chan.h" #include "znc.h" #include "HTTPSock.h" #include "Server.h" class CWebAdminMod; class CWebAdminSock : public CHTTPSock { public: CWebAdminSock(CWebAdminMod* pModule); CWebAdminSock(CWebAdminMod* pModule, const CString& sHostname, unsigned short uPort, int iTimeout = 60); virtual ~CWebAdminSock(); virtual bool OnPageRequest(const CString& sURI, CString& sPageRet); virtual bool OnLogin(const CString& sUser, const CString& sPass); CString Header(const CString& sTitle); CString Footer(); void PrintMainPage(CString& sPageRet) { sPageRet = Header("Main Page"); sPageRet += "Welcome to the ZNC webadmin module.\r\n"; sPageRet += Footer(); } void GetErrorPage(CString& sPageRet, const CString& sError) { sPageRet = Header("Error"); sPageRet += "

" + sError.Escape_n(CString::EHTML) + "

\r\n"; sPageRet += Footer(); } void ListUsersPage(CString& sPageRet); bool SettingsPage(CString& sPageRet); bool ChanPage(CString& sPageRet, CChan* = NULL); bool DelChan(CString& sPageRet); bool UserPage(CString& sPageRet, CUser* pUser = NULL); CUser* GetNewUser(CString& sPageRet, CUser* pUser); void ListPage(CString& sPageRet) { VCString vsParams; const map& msvsParams = GetParams(); sPageRet = Header("fooooooo"); if (msvsParams.empty()) { sPageRet += "You passed in no params.\r\n"; } else { sPageRet += "foo [" + GetParamString().Escape_n(CString::EHTML) + "]

"; for (map::const_iterator it = msvsParams.begin(); it != msvsParams.end(); it++) { sPageRet += "

" + it->first + "

\r\n\r\n"; } } sPageRet += Footer(); } CString GetModArgs(const CString& sModName, bool bGlobal = false) { if (!bGlobal && !m_pUser) { return ""; } CModules& Modules = (bGlobal) ? CZNC::New()->GetModules() : m_pUser->GetModules(); for (unsigned int a = 0; a < Modules.size(); a++) { CModule* pModule = Modules[a]; if (pModule->GetModName() == sModName) { return pModule->GetArgs(); } } return ""; } virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort); bool IsAdmin() const { return m_bAdmin; } private: protected: CWebAdminMod* m_pModule; CUser* m_pUser; bool m_bAdmin; }; class CWebAdminMod : public CGlobalModule { public: CWebAdminMod(void *pDLL, CZNC* pZNC, const CString& sModName) : CGlobalModule(pDLL, pZNC, sModName) { m_uPort = 8080; } virtual ~CWebAdminMod() { for (set::iterator it = m_sSocks.begin(); it != m_sSocks.end(); it++) { m_pManager->DelSockByAddr(*it); } } virtual bool OnBoot() { return true; } virtual bool OnLoad(const CString& sArgs) { bool bSSL = false; CString sPort = sArgs.Token(0); if (sPort.Left(1) == "+") { #ifdef HAVE_LIBSSL sPort.TrimLeft("+"); bSSL = true; #else return false; #endif } m_uPort = sPort.ToUInt(); m_sUser = sArgs.Token(1); m_sPass = sArgs.Token(2); if (m_sPass.empty()) { return false; } CWebAdminSock* pListenSock = new CWebAdminSock(this); #ifdef HAVE_LIBSSL if (bSSL) { pListenSock->SetPemLocation(m_pZNC->GetPemLocation()); } #endif return m_pManager->ListenAll(m_uPort, "WebAdmin::Listener", bSSL, SOMAXCONN, pListenSock); } void AddSock(CWebAdminSock* pSock) { m_sSocks.insert(pSock); } void SockDestroyed(CWebAdminSock* pSock) { m_sSocks.erase(pSock); } const CString& GetUser() const { return m_sUser; } const CString& GetPass() const { return m_sPass; } private: unsigned int m_uPort; CString m_sUser; CString m_sPass; set m_sSocks; }; CString CWebAdminSock::Header(const CString& sTitle) { CString sRet = "\r\n" "\r\nZNC - " + sTitle.Escape_n(CString::EHTML) + "\r\n" "\r\n" "\r\n" "\r\n" "\r\n" "

" + sTitle.Escape_n(CString::EHTML) + "

\r\n"; if (IsAdmin()) { sRet += "[Home]
\r\n" "[Settings]
\r\n" "[Add User]
\r\n" "[List Users]
\r\n"; } sRet += "
\r\n"; return sRet; } CString CWebAdminSock::Footer() { return "
" + m_pModule->GetZNC()->GetTag() + "
\r\n\r\n"; } bool CWebAdminSock::OnLogin(const CString& sUser, const CString& sPass) { if (GetUser() == m_pModule->GetUser() && GetPass() == m_pModule->GetPass()) { m_bAdmin = true; return true; } CUser* pUser = m_pModule->GetZNC()->FindUser(GetUser()); if (pUser && pUser->CheckPass(GetPass())) { m_pUser = pUser; return true; } return false; } void CWebAdminSock::ListUsersPage(CString& sPageRet) { const map& msUsers = m_pModule->GetZNC()->GetUserMap(); sPageRet = Header("List Users"); if (!msUsers.size()) { sPageRet += "There are no users defined. Click here if you would like to add one.\r\n"; } else { sPageRet += "\r\n" "\t\r\n"; unsigned int a = 0; for (map::const_iterator it = msUsers.begin(); it != msUsers.end(); it++, a++) { CServer* pServer = it->second->GetCurrentServer(); sPageRet += "\t\r\n\t\t\r\n" "\t\t\r\n" "\t\t\r\n" "\t"; } sPageRet +="\r\n
ActionUsernameCurrent Server
[second->GetUserName().Escape_n(CString::EURL) + "\">Edit] [second->GetUserName().Escape_n(CString::EURL) + "\">Delete]" + it->second->GetUserName().Escape_n(CString::EHTML) + "" + CString((pServer) ? pServer->GetName().Escape_n(CString::EHTML) : "-N/A-") + "
\r\n"; } sPageRet += Footer(); } Csock* CWebAdminSock::GetSockObj(const CString& sHost, unsigned short uPort) { CWebAdminSock* pSock = new CWebAdminSock(m_pModule, sHost, uPort); pSock->SetSockName("WebAdmin::Client"); pSock->SetTimeout(120); m_pModule->AddSock(pSock); return pSock; } CWebAdminSock::CWebAdminSock(CWebAdminMod* pModule) : CHTTPSock() { m_pModule = pModule; m_pUser = NULL; m_bAdmin = false; m_pModule->AddSock(this); } CWebAdminSock::CWebAdminSock(CWebAdminMod* pModule, const CString& sHostname, unsigned short uPort, int iTimeout) : CHTTPSock(sHostname, uPort, iTimeout) { m_pModule = pModule; m_pUser = NULL; m_bAdmin = false; m_pModule->AddSock(this); } CWebAdminSock::~CWebAdminSock() { m_pModule->SockDestroyed(this); } bool CWebAdminSock::OnPageRequest(const CString& sURI, CString& sPageRet) { DEBUG_ONLY(cout << "Request for [" << sURI << "] "); if (!ForceLogin()) { DEBUG_ONLY(cout << "- User not logged in!" << endl); return false; } if (sURI == "/") { if (!IsAdmin()) { Redirect("/edituser"); return false; } PrintMainPage(sPageRet); } else if (sURI == "/settings") { if (!IsAdmin()) { return false; } if (!SettingsPage(sPageRet)) { DEBUG_ONLY(cout << "- 302 Redirect" << endl); return false; } } else if (sURI == "/adduser") { if (!IsAdmin()) { return false; } if (!UserPage(sPageRet)) { DEBUG_ONLY(cout << "- 302 Redirect" << endl); return false; } } else if (sURI == "/edituser") { if (!m_pUser) { m_pUser = m_pModule->GetZNC()->FindUser(GetParam("user")); } if (m_pUser) { if (!UserPage(sPageRet, m_pUser)) { DEBUG_ONLY(cout << "- 302 Redirect" << endl); return false; } } else { GetErrorPage(sPageRet, "No such username"); } } else if (sURI == "/editchan") { if (!m_pUser) { m_pUser = m_pModule->GetZNC()->FindUser(GetParam("user")); } if (!m_pUser) { GetErrorPage(sPageRet, "No such username"); return true; } CChan* pChan = m_pUser->FindChan(GetParam("chan")); if (!pChan) { GetErrorPage(sPageRet, "No such channel"); cerr << "==== [" << GetParam("chan") << "] == [" << (int) pChan << "]" << endl; return true; } if (!ChanPage(sPageRet, pChan)) { DEBUG_ONLY(cout << "- 302 Redirect" << endl); return false; } } else if (sURI == "/addchan") { if (!m_pUser) { m_pUser = m_pModule->GetZNC()->FindUser(GetParam("user")); } if (m_pUser) { if (!ChanPage(sPageRet)) { DEBUG_ONLY(cout << "- 302 Redirect" << endl); return false; } } else { GetErrorPage(sPageRet, "No such username"); } } else if (sURI == "/delchan") { if (!m_pUser) { m_pUser = m_pModule->GetZNC()->FindUser(GetParam("user")); } if (m_pUser) { if (!DelChan(sPageRet)) { DEBUG_ONLY(cout << "- 302 Redirect" << endl); return false; } } else { GetErrorPage(sPageRet, "No such username"); } } else if (sURI == "/listusers") { if (!IsAdmin()) { return false; } ListUsersPage(sPageRet); } else if (sURI == "/deluser") { if (!IsAdmin()) { return false; } if (m_pModule->GetZNC()->DeleteUser(GetParam("user"))) { DEBUG_ONLY(cout << "- 302 Redirect" << endl); Redirect("/listusers"); return false; } else { GetErrorPage(sPageRet, "No such username"); } //} else if (sURI == "/list") { // ListPage(sPageRet); } else { DEBUG_ONLY(cout << "- 404 Not Found!" << endl); return false; } DEBUG_ONLY(cout << "- 200 OK!" << endl); return true; } bool CWebAdminSock::SettingsPage(CString& sPageRet) { if (!GetParam("submitted").ToUInt()) { sPageRet = Header("Settings"); CString sVHosts; const VCString& vsVHosts = m_pModule->GetZNC()->GetVHosts(); for (unsigned int a = 0; a < vsVHosts.size(); a++) { sVHosts += vsVHosts[a] + "\r\n"; } sPageRet += "
\r\n" "\r\n" "
Global Settings
\r\n" "
Status Prefix:
\r\n" "

\r\n" "
ISpoofFile:
\r\n" "
\r\n" "
ISpoofFormat:
\r\n" "
\r\n" "
VHosts:
\r\n" "
\r\n" "


\r\n" "
Global Modules
\r\n" "\r\n" "\r\n"; set ssGlobalMods; m_pModule->GetZNC()->GetModules().GetAvailableMods(ssGlobalMods, m_pModule->GetZNC(), true); unsigned int uIdx = 0; for (set::iterator it = ssGlobalMods.begin(); it != ssGlobalMods.end(); it++) { const CModInfo& Info = *it; sPageRet += "" "" ""; } sPageRet += "
NameArgumentsDescription
GetModName()) ? " DISABLED" : "") + ">" + Info.GetDescription().Escape_n(CString::EHTML) + "



\r\n" "


\r\n" "\r\n" "
\r\n"; sPageRet += Footer(); return true; } CString sArg; sArg = GetParam("statusprefix"); m_pModule->GetZNC()->SetStatusPrefix(sArg); sArg = GetParam("ispooffile"); m_pModule->GetZNC()->SetISpoofFile(sArg); sArg = GetParam("ispoofformat"); m_pModule->GetZNC()->SetISpoofFormat(sArg); //sArg = GetParam(""); if (!sArg.empty()) { m_pModule->GetZNC()->Set(sArg); } VCString vsArgs = GetParam("vhosts").Split("\n"); m_pModule->GetZNC()->ClearVHosts(); unsigned int a = 0; for (a = 0; a < vsArgs.size(); a++) { m_pModule->GetZNC()->AddVHost(vsArgs[a].Trim_n()); } set ssArgs; GetParamValues("loadmod", ssArgs); for (set::iterator it = ssArgs.begin(); it != ssArgs.end(); it++) { CString sModRet; CString sModName = (*it).TrimRight_n("\r"); if (!sModName.empty()) { CString sArgs = GetParam("modargs_" + sModName); try { if (!m_pModule->GetZNC()->GetModules().FindModule(sModName)) { if (!m_pModule->GetZNC()->GetModules().LoadModule(sModName, sArgs, NULL, sModRet)) { DEBUG_ONLY(cerr << "Unable to load module [" << sModName << "] [" << sModRet << "]" << endl); } } else { DEBUG_ONLY(cerr << "Unable to load module [" << sModName << "] because it is already loaded" << endl); } } catch(...) { DEBUG_ONLY(cerr << "Unable to load module [" << sModName << "] [" << sArgs << "]" << endl); } } } const CModules& vCurMods = m_pModule->GetZNC()->GetModules(); set ssUnloadMods; for (a = 0; a < vCurMods.size(); a++) { CModule* pCurMod = vCurMods[a]; if (ssArgs.find(pCurMod->GetModName()) == ssArgs.end() && pCurMod->GetModName() != m_pModule->GetModName()) { ssUnloadMods.insert(pCurMod->GetModName()); } } for (set::iterator it2 = ssUnloadMods.begin(); it2 != ssUnloadMods.end(); it2++) { m_pModule->GetZNC()->GetModules().UnloadModule(*it2); } if (!m_pModule->GetZNC()->WriteConfig()) { GetErrorPage(sPageRet, "Settings changed, but config was not written"); return true; } Redirect("/"); return false; } bool CWebAdminSock::ChanPage(CString& sPageRet, CChan* pChan) { if (!m_pUser) { GetErrorPage(sPageRet, "That user doesn't exist"); } if (!GetParam("submitted").ToUInt()) { sPageRet = Header(CString((pChan) ? "Edit" : "Add") + " Channel" + CString((pChan) ? (" [" + pChan->GetName() + "]") : "") + " for User [" + m_pUser->GetUserName() + "]"); sPageRet += "
\r\n" "\r\n" "\r\n"; if (pChan) { sPageRet += "\r\n"; } sPageRet += "
Channel Info
\r\n" "\r\n" "\r\n" "\r\n"; } else { sPageRet += "\r\n"; } sPageRet += "\r\n" "\r\n" "\r\n" "\r\n" "\r\n" "\r\n" "\r\n" "
Channel Name:
\r\n"; if (pChan) { sPageRet += "" + pChan->GetName().Escape_n(CString::EHTML) + "
Buffer Count:
\r\n" "
Default Modes:
\r\n" "
Save:
\r\n" "
Options:
\r\n" "\r\n" "\r\n" "\r\n" "
\r\n" "


\r\n" "\r\n" "
\r\n"; sPageRet += Footer(); return true; } CString sChanName = GetParam("name"); if (!pChan) { if (sChanName.empty()) { GetErrorPage(sPageRet, "Channel name is a required argument"); return true; } pChan = new CChan(sChanName, m_pUser, true); m_pUser->AddChan(pChan); } pChan->SetDefaultModes(GetParam("defmodes")); pChan->SetBufferCount(GetParam("buffercount").ToUInt()); pChan->SetInConfig(GetParam("save").ToBool()); pChan->SetAutoCycle(GetParam("autocycle").ToBool()); pChan->SetKeepBuffer(GetParam("keepbuffer").ToBool()); bool bDetached = GetParam("detached").ToBool(); if (pChan->IsDetached() != bDetached) { if (bDetached) { pChan->DetachUser(); } else { pChan->AttachUser(); } } if (!m_pModule->GetZNC()->WriteConfig()) { GetErrorPage(sPageRet, "Channel added/modified, but config was not written"); return true; } Redirect("/edituser?user=" + m_pUser->GetUserName().Escape_n(CString::EURL)); return false; } bool CWebAdminSock::DelChan(CString& sPageRet) { CString sChan = GetParam("chan"); if (!m_pUser) { GetErrorPage(sPageRet, "That user doesn't exist"); return true; } if (sChan.empty()) { GetErrorPage(sPageRet, "That channel doesn't exist for this user"); return true; } m_pUser->DelChan(sChan); m_pUser->PutIRC("PART " + sChan); Redirect("/edituser?user=" + m_pUser->GetUserName().Escape_n(CString::EURL)); return false; } bool CWebAdminSock::UserPage(CString& sPageRet, CUser* pUser) { if (!GetParam("submitted").ToUInt()) { sPageRet = Header((pUser) ? CString("Edit User [" + pUser->GetUserName() + "]") : CString("Add User")); CString sAllowedHosts, sServers, sChans, sCTCPReplies; if (pUser) { const set& ssAllowedHosts = pUser->GetAllowedHosts(); for (set::const_iterator it = ssAllowedHosts.begin(); it != ssAllowedHosts.end(); it++) { sAllowedHosts += *it + "\r\n"; } const vector& vServers = pUser->GetServers(); for (unsigned int a = 0; a < vServers.size(); a++) { sServers += vServers[a]->GetString() + "\r\n"; } const vector& vChans = pUser->GetChans(); for (unsigned int b = 0; b < vChans.size(); b++) { CChan* pChan = vChans[b]; if (pChan->InConfig()) { sChans += vChans[b]->GetName() + "\r\n"; } } const MCString& msCTCPReplies = pUser->GetCTCPReplies(); for (MCString::const_iterator it2 = msCTCPReplies.begin(); it2 != msCTCPReplies.end(); it2++) { sCTCPReplies += it2->first + " " + it2->second + "\r\n"; } } sPageRet += "
\r\n"; sPageRet += "\r\n" "
Authentication
\r\n" "
Username:
\r\n"; if (pUser) { sPageRet += "\r\n" "
\r\n"; } else { sPageRet += "
\r\n"; } sPageRet += "Password:

\r\n" "Confirm Password:
\r\n" "
Allowed IPs:
\r\n" "


\r\n" "
IRC Information
\r\n" "
Nick:
\r\n" "
\r\n" "
AltNick:
\r\n" "
\r\n" "
AwaySuffix:
\r\n" "
\r\n" "
StatusPrefix:
\r\n" "

\r\n" "
Ident:
\r\n" "
\r\n" "
RealName:
\r\n" "

\r\n"; const VCString& vsVHosts = m_pModule->GetZNC()->GetVHosts(); if (vsVHosts.size()) { sPageRet += "VHost:
\r\n" "

\r\n"; } sPageRet += "QuitMsg:
\r\n" "

\r\n" "
Servers:
\r\n" "
\r\n" "


\r\n" "
Modules
\r\n" "\r\n" "\r\n"; set ssUserMods; m_pModule->GetZNC()->GetModules().GetAvailableMods(ssUserMods, m_pModule->GetZNC()); unsigned int uIdx = 0; for (set::iterator it = ssUserMods.begin(); it != ssUserMods.end(); it++) { const CModInfo& Info = *it; sPageRet += ""; if (!IsAdmin() && pUser && pUser->DenyLoadMod()) { CString sArgs = GetModArgs(Info.GetName()).Escape_n(CString::EHTML); if (sArgs.empty()) { sArgs = " "; } sPageRet += ""; } else { sPageRet += ""; } sPageRet += ""; } CString sURL = "/addchan?user=" + pUser->GetUserName().Escape_n(CString::EURL); sPageRet += "
NameArgumentsDescription
" + sArgs + "" + Info.GetDescription().Escape_n(CString::EHTML) + "



\r\n" "
Channels
\r\n" "Default Modes:
\r\n" "

\r\n" "\r\n" "\r\n" "\r\n"; const vector& Channels = pUser->GetChans(); if (!Channels.size()) { sPageRet += "\r\n"; } else { sPageRet += "\r\n" "\r\n" "\r\n" "\r\n" "\r\n" "\r\n"; } sPageRet += "\r\n"; for (unsigned int a = 0; a < Channels.size(); a++) { CChan* pChan = Channels[a]; CString sURL = "user=" + pUser->GetUserName().Escape_n(CString::EURL) + "&chan=" + pChan->GetName().Escape_n(CString::EURL); sPageRet += "" "\r\n" "\r\n" "\r\n" "\r\n" "\r\n" "\r\n" "\r\n" "\r\n"; } sPageRet += "
[Add  <- Add a channel (opens in same page)  SaveNameCurModesDefModesBufferCountOptions
" "\r\n" "[Edit] [DelInConfig()) ? " CHECKED" : "") + "> " + CString(pChan->GetPermStr() + pChan->GetName()).Escape_n(CString::EHTML) + " " + pChan->GetModeString().Escape_n(CString::EHTML) + " " + pChan->GetDefaultModes().Escape_n(CString::EHTML) + " " + CString::ToString(pChan->GetBufferCount()) + " " + pChan->GetOptions().Escape_n(CString::EHTML) + " 



\r\n" "
ZNC Behavior
\r\n" "Playback Buffer Size:
\r\n" "

\r\n" "Options:
\r\n" "  \r\n" "  \r\n" "  \r\n" "  \r\n" "  \r\n"; if (IsAdmin()) { sPageRet += "  \r\n"; } sPageRet += "

" "
CTCP Replies:
" "
\r\n" "


\r\n" "\r\n" "
\r\n"; sPageRet += Footer(); return true; } CString sUsername = GetParam("user"); if (!pUser && m_pModule->GetZNC()->FindUser(sUsername)) { GetErrorPage(sPageRet, "Invalid Submission [User " + sUsername + " already exists]"); return true; } CUser* pNewUser = GetNewUser(sPageRet, pUser); if (!pNewUser) { return true; } CString sErr; if (!pUser) { // Add User Submission if (!pNewUser->IsValid(sErr)) { delete pNewUser; GetErrorPage(sPageRet, "Invalid submission [" + sErr + "]"); return true; } m_pModule->GetZNC()->AddUser(pNewUser); if (!m_pModule->GetZNC()->WriteConfig()) { GetErrorPage(sPageRet, "User added, but config was not written"); return true; } } else { // Edit User Submission if (!pUser->Clone(*pNewUser, sErr)) { delete pNewUser; GetErrorPage(sPageRet, "Invalid Submission [" + sErr + "]"); return true; } delete pNewUser; if (!m_pModule->GetZNC()->WriteConfig()) { GetErrorPage(sPageRet, "User edited, but config was not written"); return true; } } if (!IsAdmin()) { Redirect("/edituser"); } else { Redirect("/listusers"); } return false; } CUser* CWebAdminSock::GetNewUser(CString& sPageRet, CUser* pUser) { CString sUsername = GetParam("newuser"); if (sUsername.empty()) { sUsername = GetParam("user"); } if (sUsername.empty()) { GetErrorPage(sPageRet, "Invalid Submission [Username is required]"); return NULL; } CString sArg = GetParam("password"); if (sArg != GetParam("password2")) { GetErrorPage(sPageRet, "Invalid Submission [Passwords do not match]"); return NULL; } CUser* pNewUser = new CUser(sUsername, m_pModule->GetZNC()); if (!sArg.empty()) { pNewUser->SetPass(sArg.MD5(), true); } VCString vsArgs; GetParam("servers").Split("\n", vsArgs); unsigned int a = 0; for (a = 0; a < vsArgs.size(); a++) { pNewUser->AddServer(vsArgs[a].Trim_n()); } GetParam("allowedips").Split("\n", vsArgs); for (a = 0; a < vsArgs.size(); a++) { pNewUser->AddAllowedHost(vsArgs[a].Trim_n()); } GetParam("ctcpreplies").Split("\n", vsArgs); for (a = 0; a < vsArgs.size(); a++) { CString sReply = vsArgs[a].TrimRight_n("\r"); pNewUser->AddCTCPReply(sReply.Token(0).Trim_n(), sReply.Token(1, true).Trim_n()); } if (IsAdmin() || (pUser && !pUser->DenyLoadMod())) { GetParamValues("loadmod", vsArgs); for (a = 0; a < vsArgs.size(); a++) { CString sModRet; CString sModName = vsArgs[a].TrimRight_n("\r"); if (!sModName.empty()) { CString sArgs = GetParam("modargs_" + sModName); try { if (!pNewUser->GetModules().LoadModule(sModName, sArgs, pNewUser, sModRet)) { DEBUG_ONLY(cerr << "Unable to load module [" << sModName << "] [" << sModRet << "]" << endl); } } catch (...) { DEBUG_ONLY(cerr << "Unable to load module [" << sModName << "] [" << sArgs << "]" << endl); } } } } else if (pUser) { CModules& Modules = pUser->GetModules(); for (a = 0; a < Modules.size(); a++) { CString sModName = Modules[a]->GetModName(); CString sArgs = Modules[a]->GetArgs(); CString sModRet; try { if (!pNewUser->GetModules().LoadModule(sModName, sArgs, pNewUser, sModRet)) { DEBUG_ONLY(cerr << "Unable to load module [" << sModName << "] [" << sModRet << "]" << endl); } } catch (...) { DEBUG_ONLY(cerr << "Unable to load module [" << sModName << "]" << endl); } } } sArg = GetParam("nick"); if (!sArg.empty()) { pNewUser->SetNick(sArg); } sArg = GetParam("altnick"); if (!sArg.empty()) { pNewUser->SetAltNick(sArg); } sArg = GetParam("awaysuffix"); if (!sArg.empty()) { pNewUser->SetAwaySuffix(sArg); } sArg = GetParam("statusprefix"); if (!sArg.empty()) { pNewUser->SetStatusPrefix(sArg); } sArg = GetParam("ident"); if (!sArg.empty()) { pNewUser->SetIdent(sArg); } sArg = GetParam("realname"); if (!sArg.empty()) { pNewUser->SetRealName(sArg); } sArg = GetParam("vhost"); if (!sArg.empty()) { pNewUser->SetVHost(sArg); } sArg = GetParam("quitmsg"); if (!sArg.empty()) { pNewUser->SetQuitMsg(sArg); } sArg = GetParam("chanmodes"); if (!sArg.empty()) { pNewUser->SetDefaultChanModes(sArg); } pNewUser->SetBufferCount(GetParam("bufsize").ToUInt()); pNewUser->SetKeepBuffer(GetParam("keepbuffer").ToBool()); pNewUser->SetBounceDCCs(GetParam("bouncedccs").ToBool()); pNewUser->SetAutoCycle(GetParam("autocycle").ToBool()); pNewUser->SetKeepNick(GetParam("keepnick").ToBool()); pNewUser->SetUseClientIP(GetParam("useclientip").ToBool()); if (IsAdmin()) { pNewUser->SetDenyLoadMod(GetParam("denyloadmod").ToBool()); } else if (pUser) { pNewUser->SetDenyLoadMod(pUser->DenyLoadMod()); } GetParamValues("channel", vsArgs); for (a = 0; a < vsArgs.size(); a++) { const CString& sChan = vsArgs[a]; pNewUser->AddChan(sChan.TrimRight_n("\r"), GetParam("save_" + sChan).ToBool()); } return pNewUser; } GLOBALMODULEDEFS(CWebAdminMod, "Dynamic configuration of users/settings through a web browser")