diff options
32 files changed, 148 insertions, 166 deletions
diff --git a/include/modules/nickserv/account.h b/include/modules/nickserv/account.h index c5717cf91..f0ba144f7 100644 --- a/include/modules/nickserv/account.h +++ b/include/modules/nickserv/account.h @@ -31,20 +31,13 @@ class CoreExport Account : public Serialize::Object public: static constexpr const char *const NAME = "account"; - /* Set if this user is a services operattor. o->ot must exist. */ - Serialize::Reference<Oper> o; - - /* Unsaved data */ - /* Last time an email was sent to this user */ time_t lastmail = 0; /* Users online now logged into this account */ std::vector<User *> users; - protected: using Serialize::Object::Object; - public: virtual Anope::string GetDisplay() anope_abstract; virtual void SetDisplay(const Anope::string &) anope_abstract; @@ -57,16 +50,14 @@ class CoreExport Account : public Serialize::Object virtual Anope::string GetLanguage() anope_abstract; virtual void SetLanguage(const Anope::string &) anope_abstract; + virtual Oper *GetOper() anope_abstract; + virtual void SetOper(Oper *) anope_abstract; + /** Changes the display for this account * @param na The new display, must be grouped to this account. */ virtual void SetDisplay(Nick *na) anope_abstract; - /** Checks whether this account is a services oper or not. - * @return True if this account is a services oper, false otherwise. - */ - virtual bool IsServicesOper() const anope_abstract; - /** Is the given user on this accounts access list? * * @param u The user @@ -80,4 +71,4 @@ class CoreExport Account : public Serialize::Object virtual unsigned int GetChannelCount() anope_abstract; }; -} // namespace NickServ
\ No newline at end of file +} // namespace NickServ diff --git a/include/opertype.h b/include/opertype.h index da8460e44..2d36dfad6 100644 --- a/include/opertype.h +++ b/include/opertype.h @@ -33,9 +33,6 @@ class Oper : public Serialize::Object public: static constexpr const char *const NAME = "oper"; - Configuration::Conf *conf = nullptr; - Module *owner = nullptr; - using Serialize::Object::Object; Anope::string GetName(); @@ -59,6 +56,9 @@ class Oper : public Serialize::Object bool GetRequireOper(); void SetRequireOper(const bool &); + bool HasCommand(const Anope::string &cmdstr); + bool HasPriv(const Anope::string &cmdstr); + /** Find an oper block by name * @param name The name * @return the oper block diff --git a/modules/chanserv/main/chanserv.cpp b/modules/chanserv/main/chanserv.cpp index 816e3031b..c6b30c2df 100644 --- a/modules/chanserv/main/chanserv.cpp +++ b/modules/chanserv/main/chanserv.cpp @@ -295,7 +295,7 @@ class ChanServCore : public Module if (ci->GetFounder() == nc) { NickServ::Account *newowner = NULL; - if (ci->GetSuccessor() && ci->GetSuccessor() != nc && (ci->GetSuccessor()->IsServicesOper() || !max_reg || ci->GetSuccessor()->GetChannelCount() < max_reg)) + if (ci->GetSuccessor() && ci->GetSuccessor() != nc && (ci->GetSuccessor()->GetOper() || !max_reg || ci->GetSuccessor()->GetChannelCount() < max_reg)) newowner = ci->GetSuccessor(); else { @@ -305,7 +305,7 @@ class ChanServCore : public Module ChanServ::ChanAccess *ca = ci->GetAccess(j); NickServ::Account *anc = ca->GetAccount(); - if (!anc || (!anc->IsServicesOper() && max_reg && anc->GetChannelCount() >= max_reg) || (anc == nc)) + if (!anc || (!anc->GetOper() && max_reg && anc->GetChannelCount() >= max_reg) || (anc == nc)) continue; if (!highest || *ca > *highest) highest = ca; diff --git a/modules/database/flatfile.cpp b/modules/database/flatfile.cpp index a130ed0ed..7483b2d34 100644 --- a/modules/database/flatfile.cpp +++ b/modules/database/flatfile.cpp @@ -47,6 +47,7 @@ class DBFlatFile : public Module account->SetPassword(data["pass"]); account->SetEmail(data["email"]); account->SetLanguage(data["language"]); + account->SetOper(Oper::Find(account->GetDisplay())); spacesepstream sep = data["access"]; for (Anope::string token; sep.GetToken(token);) diff --git a/modules/extra/sql_oper.cpp b/modules/extra/sql_oper.cpp index 17c825828..9dfcfe772 100644 --- a/modules/extra/sql_oper.cpp +++ b/modules/extra/sql_oper.cpp @@ -33,10 +33,10 @@ class SQLOperResult : public SQL::Interface void Deoper() { - if (user->Account()->o && user->Account()->o->owner == this->owner) + Oper *oper = user->Account()->GetOper(); + if (oper != nullptr) { - user->Account()->o->Delete(); - user->Account()->o = nullptr; + oper->Delete(); Log(this->owner) << "Removed services operator from " << user->nick << " (" << user->Account()->GetDisplay() << ")"; user->RemoveMode(Config->GetClient("OperServ"), "OPER"); // Probably not set, just incase @@ -94,25 +94,19 @@ class SQLOperResult : public SQL::Interface return; } - if (user->Account()->o && user->Account()->o->owner != this->owner) - { - Log(this->owner) << "Oper " << user->Account()->GetDisplay() << " has type " << ot->GetName() << ", but is already configured as an oper of type " << user->Account()->o->GetType()->GetName(); - return; - } - - if (!user->Account()->o || user->Account()->o->GetType() != ot) + Oper *oper = user->Account()->GetOper(); + if (oper == nullptr || oper->GetType() != ot) { Log(this->owner) << "m_sql_oper: Tieing oper " << user->nick << " to type " << opertype; - if (user->Account()->o) - user->Account()->o->Delete(); + if (oper) + oper->Delete(); - Oper *o = Serialize::New<Oper *>(); - o->owner = this->owner; - o->SetName(user->Account()->GetDisplay()); - o->SetType(ot); + oper = Serialize::New<Oper *>(); + oper->SetName(user->Account()->GetDisplay()); + oper->SetType(ot); - user->Account()->o = o; + user->Account()->SetOper(oper); } if (!user->HasMode("OPER")) @@ -145,24 +139,6 @@ class ModuleSQLOper : public Module { } - ~ModuleSQLOper() - { - if (NickServ::service == nullptr) - return; - - NickServ::nickcore_map& map = NickServ::service->GetAccountMap(); - for (NickServ::nickcore_map::const_iterator it = map.begin(); it != map.end(); ++it) - { - NickServ::Account *nc = it->second; - - if (nc->o && nc->o->owner == this) - { - nc->o->Delete(); - nc->o = nullptr; - } - } - } - void OnReload(Configuration::Conf *conf) override { Configuration::Block *config = conf->GetModule(this); diff --git a/modules/memoserv/staff.cpp b/modules/memoserv/staff.cpp index 45883bbb6..6b176925f 100644 --- a/modules/memoserv/staff.cpp +++ b/modules/memoserv/staff.cpp @@ -37,7 +37,7 @@ class CommandMSStaff : public Command const Anope::string &text = params[0]; for (NickServ::Account *nc : NickServ::service->GetAccountList()) - if (source.nc != nc && nc->IsServicesOper()) + if (source.nc != nc && nc->GetOper()) MemoServ::service->Send(source.GetNick(), nc->GetDisplay(), text, true); } diff --git a/modules/nickserv/access.cpp b/modules/nickserv/access.cpp index 48d2e3bdc..1f3622afa 100644 --- a/modules/nickserv/access.cpp +++ b/modules/nickserv/access.cpp @@ -189,7 +189,7 @@ class CommandNSAccess : public Command return; } - if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->GetAccount() && na->GetAccount()->IsServicesOper() && !cmd.equals_ci("LIST")) + if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->GetAccount() && na->GetAccount()->GetOper() && !cmd.equals_ci("LIST")) { source.Reply(_("You may view but not modify the access list of other Services Operators.")); return; diff --git a/modules/nickserv/cert.cpp b/modules/nickserv/cert.cpp index 3f3ea3a5a..f84d32cea 100644 --- a/modules/nickserv/cert.cpp +++ b/modules/nickserv/cert.cpp @@ -270,7 +270,7 @@ class CommandNSCert : public Command return; } - if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->GetAccount() && na->GetAccount()->IsServicesOper() && !cmd.equals_ci("LIST")) + if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->GetAccount() && na->GetAccount()->GetOper() && !cmd.equals_ci("LIST")) { source.Reply(_("You may view, but not modify, the certificate list of other Services Operators.")); return; diff --git a/modules/nickserv/drop.cpp b/modules/nickserv/drop.cpp index f4a109573..426e3115e 100644 --- a/modules/nickserv/drop.cpp +++ b/modules/nickserv/drop.cpp @@ -55,7 +55,7 @@ class CommandNSDrop : public Command return; } - if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && !is_mine && na->GetAccount()->IsServicesOper()) + if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && !is_mine && na->GetAccount()->GetOper()) { source.Reply(_("You may not drop other Services Operators' nicknames.")); return; diff --git a/modules/nickserv/group.cpp b/modules/nickserv/group.cpp index 68e59ad7f..ea62a9012 100644 --- a/modules/nickserv/group.cpp +++ b/modules/nickserv/group.cpp @@ -178,7 +178,7 @@ class CommandNSGroup : public Command return; } - if (maxaliases && target->GetAccount()->GetRefs<NickServ::Nick *>().size() >= maxaliases && !target->GetAccount()->IsServicesOper()) + if (maxaliases && target->GetAccount()->GetRefs<NickServ::Nick *>().size() >= maxaliases && !target->GetAccount()->GetOper()) { source.Reply(_("There are too many nicknames in your group.")); return; diff --git a/modules/nickserv/info.cpp b/modules/nickserv/info.cpp index 9b916ff60..08614315e 100644 --- a/modules/nickserv/info.cpp +++ b/modules/nickserv/info.cpp @@ -65,8 +65,8 @@ class CommandNSInfo : public Command if (na->GetAccount()->HasFieldS("UNCONFIRMED")) source.Reply(_("\002{0}\002 has not confirmed their account."), na->GetNick()); - if (na->GetAccount()->IsServicesOper() && (show_hidden || !na->GetAccount()->HasFieldS("HIDE_STATUS"))) - source.Reply(_("\002{0}\002 is a Services Operator of type \002{1}\002."), na->GetNick(), na->GetAccount()->o->GetType()->GetName()); + if (na->GetAccount()->GetOper() && (show_hidden || !na->GetAccount()->HasFieldS("HIDE_STATUS"))) + source.Reply(_("\002{0}\002 is a Services Operator of type \002{1}\002."), na->GetNick(), na->GetAccount()->GetOper()->GetType()->GetName()); InfoFormatter info(source.nc); diff --git a/modules/nickserv/main/account.cpp b/modules/nickserv/main/account.cpp index 1c2266e59..1cd868194 100644 --- a/modules/nickserv/main/account.cpp +++ b/modules/nickserv/main/account.cpp @@ -77,6 +77,16 @@ void AccountImpl::SetLanguage(const Anope::string &lang) Set(&AccountType::language, lang); } +Oper *AccountImpl::GetOper() +{ + return Get(&AccountType::oper); +} + +void AccountImpl::SetOper(Oper *oper) +{ + Set(&AccountType::oper, oper); +} + MemoServ::MemoInfo *AccountImpl::GetMemos() { return GetRef<MemoServ::MemoInfo *>(); @@ -103,11 +113,6 @@ void AccountImpl::SetDisplay(NickServ::Nick *na) nc = this; } -bool AccountImpl::IsServicesOper() const -{ - return this->o != NULL; -} - bool AccountImpl::IsOnAccess(User *u) { Anope::string buf = u->GetIdent() + "@" + u->host, buf2, buf3; diff --git a/modules/nickserv/main/account.h b/modules/nickserv/main/account.h index 461a3d865..611233261 100644 --- a/modules/nickserv/main/account.h +++ b/modules/nickserv/main/account.h @@ -24,10 +24,10 @@ class AccountImpl : public NickServ::Account friend class AccountType; Anope::string display, password, email, language; + Oper *oper = nullptr; public: - AccountImpl(Serialize::TypeBase *type) : NickServ::Account(type) { } - AccountImpl(Serialize::TypeBase *type, Serialize::ID id) : NickServ::Account(type, id) { } + using NickServ::Account::Account; ~AccountImpl(); void Delete() override; @@ -43,16 +43,12 @@ class AccountImpl : public NickServ::Account Anope::string GetLanguage() override; void SetLanguage(const Anope::string &) override; + Oper *GetOper() override; + void SetOper(Oper *) override; + MemoServ::MemoInfo *GetMemos() override; void SetDisplay(NickServ::Nick *na) override; - bool IsServicesOper() const override; - /*void AddAccess(const Anope::string &entry) override; - Anope::string GetAccess(unsigned entry) const override; - unsigned GetAccessCount() const override; - bool FindAccess(const Anope::string &entry) override; - void EraseAccess(const Anope::string &entry) override; - void ClearAccess() override;*/ bool IsOnAccess(User *u) override; unsigned int GetChannelCount() override; }; diff --git a/modules/nickserv/main/accounttype.cpp b/modules/nickserv/main/accounttype.cpp index 6ea32cd83..ec37c18d4 100644 --- a/modules/nickserv/main/accounttype.cpp +++ b/modules/nickserv/main/accounttype.cpp @@ -25,6 +25,7 @@ AccountType::AccountType(Module *me) : Serialize::Type<AccountImpl>(me) , pass(this, "pass", &AccountImpl::password) , email(this, "email", &AccountImpl::email) , language(this, "language", &AccountImpl::language) + , oper(this, "oper", &AccountImpl::oper) { } @@ -38,9 +39,6 @@ void AccountType::Display::OnSet(AccountImpl *acc, const Anope::string &disp) map.erase(*old); map[disp] = acc; - -#warning "this is all wrong" - acc->o = Oper::Find(disp); } NickServ::Account *AccountType::FindAccount(const Anope::string &acc) diff --git a/modules/nickserv/main/accounttype.h b/modules/nickserv/main/accounttype.h index 27efd90dd..8e831ed2c 100644 --- a/modules/nickserv/main/accounttype.h +++ b/modules/nickserv/main/accounttype.h @@ -34,7 +34,7 @@ class AccountType : public Serialize::Type<AccountImpl> Serialize::Field<AccountImpl, Anope::string> email; /* Locale name of the language of the user. Empty means default language */ Serialize::Field<AccountImpl, Anope::string> language; - + Serialize::ObjectField<AccountImpl, Oper *> oper; AccountType(Module *); diff --git a/modules/nickserv/register.cpp b/modules/nickserv/register.cpp index e3d4d4d23..471ca57fa 100644 --- a/modules/nickserv/register.cpp +++ b/modules/nickserv/register.cpp @@ -233,6 +233,7 @@ class CommandNSRegister : public Command NickServ::Account *nc = Serialize::New<NickServ::Account *>(); nc->SetDisplay(u_nick); + nc->SetOper(Oper::Find(u_nick)); NickServ::Nick *na = Serialize::New<NickServ::Nick *>(); na->SetNick(u_nick); diff --git a/modules/nickserv/set.cpp b/modules/nickserv/set.cpp index 7b1034eca..4be031690 100644 --- a/modules/nickserv/set.cpp +++ b/modules/nickserv/set.cpp @@ -198,7 +198,7 @@ class CommandNSSASetPassword : public Command size_t len = params[1].length(); - if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper()) + if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->GetOper()) { source.Reply(_("You may not change the password of other Services Operators.")); return; @@ -464,7 +464,7 @@ class CommandNSSetEmail : public Command return; } - if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper()) + if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->GetOper()) { source.Reply(_("You may not change the e-mail of other Services Operators.")); return; diff --git a/modules/nickserv/suspend.cpp b/modules/nickserv/suspend.cpp index 8f436e682..e252eb67c 100644 --- a/modules/nickserv/suspend.cpp +++ b/modules/nickserv/suspend.cpp @@ -160,7 +160,7 @@ class CommandNSSuspend : public Command return; } - if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && na->GetAccount()->IsServicesOper()) + if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && na->GetAccount()->GetOper()) { source.Reply(_("You may not suspend other Services Operators' nicknames.")); return; diff --git a/modules/operserv/forbid.cpp b/modules/operserv/forbid.cpp index 36ef12870..1a013ed0d 100644 --- a/modules/operserv/forbid.cpp +++ b/modules/operserv/forbid.cpp @@ -247,7 +247,7 @@ class CommandOSForbid : public Command } NickServ::Nick *target = NickServ::FindNick(entry); - if (target != NULL && Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && target->GetAccount()->IsServicesOper()) + if (target != NULL && Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && target->GetAccount()->GetOper()) { source.Reply(_("Access denied.")); return; diff --git a/modules/operserv/login.cpp b/modules/operserv/login.cpp index 180024eac..270958875 100644 --- a/modules/operserv/login.cpp +++ b/modules/operserv/login.cpp @@ -33,7 +33,7 @@ class CommandOSLogin : public Command const Anope::string &password = params[0]; User *u = source.GetUser(); - Oper *o = source.nc->o; + Oper *o = source.nc->GetOper(); if (o == NULL) { source.Reply(_("No oper block for your nickname.")); @@ -87,7 +87,7 @@ class CommandOSLogout : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { User *u = source.GetUser(); - Oper *o = source.nc->o; + Oper *o = source.nc->GetOper(); if (o == NULL) { source.Reply(_("No oper block for your nick.")); @@ -142,7 +142,7 @@ class OSLogin : public Module EventReturn IsServicesOper(User *u) override { - if (!u->Account()->o->GetPassword().empty()) + if (!u->Account()->GetOper()->GetPassword().empty()) { if (os_login.HasExt(u)) return EVENT_ALLOW; diff --git a/modules/operserv/oper.cpp b/modules/operserv/oper.cpp index 34fcb1abc..099cfc286 100644 --- a/modules/operserv/oper.cpp +++ b/modules/operserv/oper.cpp @@ -81,18 +81,18 @@ class CommandOSOper : public Command return; } - if (na->GetAccount()->o) + Oper *o = na->GetAccount()->GetOper(); + if (o != nullptr) { - na->GetAccount()->o->Delete(); - na->GetAccount()->o = nullptr; + o->Delete(); } - Oper *o = Serialize::New<Oper *>(); + o = Serialize::New<Oper *>(); o->SetName(na->GetAccount()->GetDisplay()); o->SetType(ot); o->SetRequireOper(true); - na->GetAccount()->o = o; + na->GetAccount()->SetOper(o); if (Anope::ReadOnly) source.Reply(_("Services are in read-only mode. Any changes made may not persist.")); @@ -117,7 +117,7 @@ class CommandOSOper : public Command return; } - Oper *o = na->GetAccount()->o; + Oper *o = na->GetAccount()->GetOper(); if (o == nullptr) { @@ -131,14 +131,8 @@ class CommandOSOper : public Command return; } - if (o->conf != nullptr) - { - source.Reply(_("Oper \002{0}\002 is configured in the configuration file(s) and can not be removed by this command."), na->GetNick()); - return; - } - na->GetAccount()->o->Delete(); - na->GetAccount()->o = NULL; + o->Delete(); if (Anope::ReadOnly) source.Reply(_("Services are in read-only mode. Any changes made may not persist.")); @@ -151,12 +145,12 @@ class CommandOSOper : public Command source.Reply(_("Name Type")); for (NickServ::Account *nc : NickServ::service->GetAccountList()) { - if (!nc->o) + Oper *oper = nc->GetOper(); + + if (oper == nullptr) continue; - source.Reply(Anope::printf("%-8s %s", nc->o->GetName().c_str(), nc->o->GetType()->GetName().c_str())); - if (nc->o->conf) - source.Reply(_(" This oper is configured in the configuration file.")); + source.Reply(Anope::printf("%-8s %s", oper->GetName().c_str(), oper->GetType()->GetName().c_str())); for (User *u : nc->users) source.Reply(_(" \002{0}\002 is online using this oper block."), u->nick); } diff --git a/modules/webcpanel/pages/chanserv/access.cpp b/modules/webcpanel/pages/chanserv/access.cpp index c98ae45c8..6b08e9a0f 100644 --- a/modules/webcpanel/pages/chanserv/access.cpp +++ b/modules/webcpanel/pages/chanserv/access.cpp @@ -47,7 +47,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s } ::ChanServ::AccessGroup u_access = ci->AccessFor(na->GetAccount()); - bool has_priv = na->GetAccount()->IsServicesOper() && na->GetAccount()->o->GetType()->HasPriv("chanserv/access/modify"); + bool has_priv = na->GetAccount()->GetOper() && na->GetAccount()->GetOper()->HasPriv("chanserv/access/modify"); if (!u_access.HasPriv("ACCESS_LIST") && !has_priv) { diff --git a/modules/webcpanel/pages/chanserv/akick.cpp b/modules/webcpanel/pages/chanserv/akick.cpp index eb1c81f5a..5a7e26711 100644 --- a/modules/webcpanel/pages/chanserv/akick.cpp +++ b/modules/webcpanel/pages/chanserv/akick.cpp @@ -48,7 +48,7 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st } ::ChanServ::AccessGroup u_access = ci->AccessFor(na->GetAccount()); - bool has_priv = na->GetAccount()->IsServicesOper() && na->GetAccount()->o->GetType()->HasPriv("chanserv/access/modify"); + bool has_priv = na->GetAccount()->GetOper() && na->GetAccount()->GetOper()->HasPriv("chanserv/access/modify"); if (!u_access.HasPriv("AKICK") && !has_priv) { diff --git a/modules/webcpanel/pages/chanserv/drop.cpp b/modules/webcpanel/pages/chanserv/drop.cpp index cc5fa4026..64ee9b9f8 100644 --- a/modules/webcpanel/pages/chanserv/drop.cpp +++ b/modules/webcpanel/pages/chanserv/drop.cpp @@ -44,7 +44,7 @@ bool WebCPanel::ChanServ::Drop::OnRequest(HTTPProvider *server, const Anope::str } for (::ChanServ::Channel *ci : na->GetAccount()->GetRefs<::ChanServ::Channel *>()) - if ((ci->HasFieldS("SECUREFOUNDER") ? ci->AccessFor(na->GetAccount()).founder : ci->AccessFor(na->GetAccount()).HasPriv("FOUNDER")) || (na->GetAccount()->IsServicesOper() && na->GetAccount()->o->GetType()->HasCommand("chanserv/drop"))) + if ((ci->HasFieldS("SECUREFOUNDER") ? ci->AccessFor(na->GetAccount()).founder : ci->AccessFor(na->GetAccount()).HasPriv("FOUNDER")) || (na->GetAccount()->GetOper() && na->GetAccount()->GetOper()->HasCommand("chanserv/drop"))) { replacements["CHANNEL_NAMES"] = ci->GetName(); replacements["ESCAPED_CHANNEL_NAMES"] = HTTPUtils::URLEncode(ci->GetName()); diff --git a/modules/webcpanel/pages/chanserv/modes.cpp b/modules/webcpanel/pages/chanserv/modes.cpp index da7ad0803..c1d0cc588 100644 --- a/modules/webcpanel/pages/chanserv/modes.cpp +++ b/modules/webcpanel/pages/chanserv/modes.cpp @@ -57,7 +57,7 @@ bool WebCPanel::ChanServ::Modes::OnRequest(HTTPProvider *server, const Anope::st } ::ChanServ::AccessGroup u_access = ci->AccessFor(na->GetAccount()); - bool has_priv = na->GetAccount()->IsServicesOper() && na->GetAccount()->o->GetType()->HasPriv("chanserv/administration"); + bool has_priv = na->GetAccount()->GetOper() && na->GetAccount()->GetOper()->HasPriv("chanserv/administration"); if (!u_access.HasPriv("MODE") && !has_priv) { diff --git a/modules/webcpanel/pages/operserv/akill.cpp b/modules/webcpanel/pages/operserv/akill.cpp index a4cdb26be..91ff4866f 100644 --- a/modules/webcpanel/pages/operserv/akill.cpp +++ b/modules/webcpanel/pages/operserv/akill.cpp @@ -25,7 +25,7 @@ WebCPanel::OperServ::Akill::Akill(const Anope::string &cat, const Anope::string bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements) { - if (!na->GetAccount()->o || !na->GetAccount()->o->GetType()->HasCommand("operserv/akill")) + if (!na->GetAccount()->GetOper() || !na->GetAccount()->GetOper()->HasCommand("operserv/akill")) { replacements["NOACCESS"]; } diff --git a/modules/webcpanel/webcpanel.h b/modules/webcpanel/webcpanel.h index 33e88821d..397e50206 100644 --- a/modules/webcpanel/webcpanel.h +++ b/modules/webcpanel/webcpanel.h @@ -112,7 +112,7 @@ class WebPanelProtectedPage : public WebPanelPage replacements["ACCOUNT"] = na->GetAccount()->GetDisplay(); replacements["PAGE_NAME"] = page_name; replacements["CATEGORY"] = category; - if (na->GetAccount()->IsServicesOper()) + if (na->GetAccount()->GetOper() != nullptr) replacements["IS_OPER"]; Anope::string sections, get; diff --git a/modules/xmlrpc_main.cpp b/modules/xmlrpc_main.cpp index cdbcf3266..dda4f4171 100644 --- a/modules/xmlrpc_main.cpp +++ b/modules/xmlrpc_main.cpp @@ -242,8 +242,8 @@ class MyXMLRPCEvent : public XMLRPCEvent if (u->Account()) { request.reply("account", iface->Sanitize(u->Account()->GetDisplay())); - if (u->Account()->o) - request.reply("opertype", iface->Sanitize(u->Account()->o->GetType()->GetName())); + if (u->Account()->GetOper()) + request.reply("opertype", iface->Sanitize(u->Account()->GetOper()->GetType()->GetName())); } Anope::string channels; diff --git a/src/command.cpp b/src/command.cpp index ade17fd45..f1cae4bb3 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -74,8 +74,10 @@ bool CommandSource::HasCommand(const Anope::string &cmd) { if (this->u) return this->u->HasCommand(cmd); - else if (this->nc && this->nc->o) - return this->nc->o->GetType()->HasCommand(cmd); + + if (this->nc && this->nc->GetOper()) + return this->nc->GetOper()->HasCommand(cmd); + return false; } @@ -83,8 +85,10 @@ bool CommandSource::HasPriv(const Anope::string &cmd) { if (this->u) return this->u->HasPriv(cmd); - else if (this->nc && this->nc->o) - return this->nc->o->GetType()->HasPriv(cmd); + + if (this->nc && this->nc->GetOper()) + return this->nc->GetOper()->HasPriv(cmd); + return false; } @@ -93,7 +97,7 @@ bool CommandSource::IsServicesOper() if (this->u) return this->u->IsServicesOper(); else if (this->nc) - return this->nc->IsServicesOper(); + return this->nc->GetOper() != nullptr; return false; } @@ -102,7 +106,7 @@ bool CommandSource::IsOper() if (this->u) return this->u->HasMode("OPER"); else if (this->nc) - return this->nc->IsServicesOper(); + return this->nc->GetOper() != nullptr; return false; } diff --git a/src/config.cpp b/src/config.cpp index e8f81c1a2..e34177e8f 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -511,18 +511,19 @@ Conf::Conf() : Block("") /* Clear existing conf opers */ if (Config) - for (Oper *o : Serialize::GetObjects<Oper *>()) - if (o->conf == Config) - o->Delete(); - /* Apply new opers */ - for (Oper *o : Serialize::GetObjects<Oper *>()) { - NickServ::Nick *na = NickServ::FindNick(o->GetName()); - if (!na) - continue; + for (int i = 0; i < Config->CountBlock("oper"); ++i) + { + Block *oper = Config->GetBlock("oper", i); - na->GetAccount()->o = o; - Log() << "Tied oper " << na->GetAccount()->GetDisplay() << " to type " << o->GetType()->GetName(); + const Anope::string &nname = oper->Get<Anope::string>("name"); + + Oper *o = Oper::Find(nname); + if (o != nullptr) + { + o->Delete(); + } + } } /* Check the user keys */ @@ -575,27 +576,6 @@ void Conf::Post(Conf *old) ModeManager::Apply(old); - /* Apply opertype changes, as non-conf opers still point to the old oper types */ - for (Oper *o : Serialize::GetObjects<Oper *>()) - { - /* Oper's type is in the old config, so update it */ - if (std::find(old->MyOperTypes.begin(), old->MyOperTypes.end(), o->GetType()) != old->MyOperTypes.end()) - { - OperType *ot = o->GetType(); - o->SetType(nullptr); - - for (unsigned j = 0; j < MyOperTypes.size(); ++j) - if (ot->GetName() == MyOperTypes[j]->GetName()) - o->SetType(MyOperTypes[j]); - - if (o->GetType() == NULL) - { - /* Oper block has lost type */ - o->Delete(); - } - } - } - for (BotInfo *bi : Serialize::GetObjects<BotInfo *>()) { if (!bi->conf) @@ -753,7 +733,6 @@ void Conf::LoadOpers() if (o == nullptr) o = Serialize::New<Oper *>(); - o->conf = this; o->SetName(nname); o->SetType(ot); o->SetRequireOper(require_oper); @@ -764,6 +743,17 @@ void Conf::LoadOpers() Log(LOG_DEBUG) << "Creating oper " << nname << " of type " << ot->GetName(); } + + /* Apply new opers */ + for (Oper *o : Serialize::GetObjects<Oper *>()) + { + NickServ::Nick *na = NickServ::FindNick(o->GetName()); + if (!na) + continue; + + na->GetAccount()->SetOper(o); + Log() << "Tied oper " << na->GetAccount()->GetDisplay() << " to type " << o->GetType()->GetName(); + } } Block *Conf::GetModule(Module *m) diff --git a/src/opertype.cpp b/src/opertype.cpp index 91676bd84..c9c1b762c 100644 --- a/src/opertype.cpp +++ b/src/opertype.cpp @@ -93,6 +93,22 @@ void Oper::SetRequireOper(const bool &b) Set(&OperBlockType::require_oper, b); } +bool Oper::HasCommand(const Anope::string &cmdstr) +{ + OperType *type = GetType(); + if (type != nullptr) + return type->HasCommand(cmdstr); + return false; +} + +bool Oper::HasPriv(const Anope::string &cmdstr) +{ + OperType *type = GetType(); + if (type != nullptr) + return type->HasPriv(cmdstr); + return false; +} + Oper *Oper::Find(const Anope::string &name) { for (Oper *o : Serialize::GetObjects<Oper *>()) diff --git a/src/users.cpp b/src/users.cpp index 3c081a918..12f61a889 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -389,9 +389,10 @@ void User::Identify(NickServ::Nick *na) EventManager::Get()->Dispatch(&Event::NickIdentify::OnNickIdentify, this); - if (this->IsServicesOper()) + Oper *oper = this->nc->GetOper(); + if (oper != nullptr && oper->GetType() != nullptr) { - Anope::string m = this->nc->o->GetType()->modes; + Anope::string m = oper->GetType()->modes; if (!m.empty()) { this->SetModes(NULL, "%s", m.c_str()); @@ -400,11 +401,11 @@ void User::Identify(NickServ::Nick *na) if (um && !this->HasMode("OPER") && m.find(um->mchar) != Anope::string::npos) IRCD->SendOper(this); } - if (IRCD->CanSetVHost && !this->nc->o->GetVhost().empty()) + if (IRCD->CanSetVHost && !oper->GetVhost().empty()) { - this->SendMessage(Me, "Changing your vhost to \002{0}\002", this->nc->o->GetVhost()); - this->SetDisplayedHost(this->nc->o->GetVhost()); - IRCD->SendVhost(this, "", this->nc->o->GetVhost()); + this->SendMessage(Me, "Changing your vhost to \002{0}\002", oper->GetVhost()); + this->SetDisplayedHost(oper->GetVhost()); + IRCD->SendVhost(this, "", oper->GetVhost()); } } } @@ -472,18 +473,26 @@ bool User::IsRecognized(bool check_secure) const bool User::IsServicesOper() { - if (!this->nc || !this->nc->IsServicesOper()) + if (!this->nc || !this->nc->GetOper()) // No opertype. return false; - else if (this->nc->o->GetRequireOper() && !this->HasMode("OPER")) + + Oper *oper = this->nc->GetOper(); + + if (oper->GetType() == nullptr) return false; - else if (!this->nc->o->GetCertFP().empty() && this->fingerprint != this->nc->o->GetCertFP()) + + if (oper->GetRequireOper() && !this->HasMode("OPER")) + return false; + + if (!oper->GetCertFP().empty() && this->fingerprint != oper->GetCertFP()) // Certfp mismatch return false; - else if (!this->nc->o->GetHost().empty()) + + if (!oper->GetHost().empty()) { std::vector<Anope::string> hosts; - spacesepstream(this->nc->o->GetHost()).GetTokens(hosts); + spacesepstream(oper->GetHost()).GetTokens(hosts); bool match = false; Anope::string match_host = this->GetIdent() + "@" + this->host; @@ -505,14 +514,14 @@ bool User::IsServicesOper() bool User::HasCommand(const Anope::string &command) { if (this->IsServicesOper()) - return this->nc->o->GetType()->HasCommand(command); + return this->nc->GetOper()->HasCommand(command); return false; } bool User::HasPriv(const Anope::string &priv) { if (this->IsServicesOper()) - return this->nc->o->GetType()->HasPriv(priv); + return this->nc->GetOper()->HasPriv(priv); return false; } @@ -556,7 +565,8 @@ void User::SetModeInternal(const MessageSource &source, UserMode *um, const Anop if (this->IsServicesOper()) { - Anope::string m = this->nc->o->GetType()->modes; + Oper *oper = this->nc->GetOper(); + Anope::string m = oper->GetType()->modes; if (!m.empty()) { this->SetModes(NULL, "%s", m.c_str()); @@ -565,11 +575,11 @@ void User::SetModeInternal(const MessageSource &source, UserMode *um, const Anop if (oper && !this->HasMode("OPER") && m.find(oper->mchar) != Anope::string::npos) IRCD->SendOper(this); } - if (IRCD->CanSetVHost && !this->nc->o->GetVhost().empty()) + if (IRCD->CanSetVHost && !oper->GetVhost().empty()) { - this->SendMessage(Me, "Changing your vhost to \002{0}\002", this->nc->o->GetVhost()); - this->SetDisplayedHost(this->nc->o->GetVhost()); - IRCD->SendVhost(this, "", this->nc->o->GetVhost()); + this->SendMessage(Me, "Changing your vhost to \002{0}\002", oper->GetVhost()); + this->SetDisplayedHost(oper->GetVhost()); + IRCD->SendVhost(this, "", oper->GetVhost()); } } } |