diff options
author | Adam <Adam@anope.org> | 2011-03-14 13:52:26 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2011-03-14 13:52:26 -0400 |
commit | ed73d7675152ccc66f20daedca8586a8de254a84 (patch) | |
tree | 18f7a1a53a717f24d061550c6670ca6f0ed54f9f | |
parent | 4fe49af8401b956249d924b89b3e69bce5fb6744 (diff) |
Rewrote some of the opertype system, added os_login
65 files changed, 393 insertions, 201 deletions
diff --git a/data/example.conf b/data/example.conf index 28ca69dc7..ee624022e 100644 --- a/data/example.conf +++ b/data/example.conf @@ -799,6 +799,12 @@ oper /* The opertype this person will have */ type = "Services Root" + + /* An optional password. If defined the user must login using /operserv login first */ + #password = "secret" + + /* An optional SSL fingerprint. If defined is required to use this opertype. */ + #certfp = "ed3383b3f7d74e89433ddaa4a6e5b2d7" } oper @@ -1493,7 +1499,7 @@ operserv * * This directive is optional, but highly recommended. */ - modules = "os_help os_global os_stats os_staff os_mode os_kick os_akill os_snline os_sqline os_szline os_chanlist os_userlist os_news os_session os_noop os_jupe os_ignore os_set os_reload os_update os_restart os_quit os_shutdown os_defcon os_chankill os_svsnick os_oline os_modload os_modunload os_modreload os_modlist os_modinfo os_config" + modules = "os_help os_global os_stats os_staff os_mode os_kick os_akill os_snline os_sqline os_szline os_chanlist os_userlist os_news os_session os_noop os_jupe os_ignore os_set os_reload os_update os_restart os_quit os_shutdown os_defcon os_chankill os_svsnick os_oline os_modload os_modunload os_modreload os_modlist os_modinfo os_config os_login" /* * If set, Services Admins will be able to use SUPERADMIN [ON|OFF] which will temporarily grant diff --git a/docs/Changes b/docs/Changes index 9d9b8be36..cde85bbd0 100644 --- a/docs/Changes +++ b/docs/Changes @@ -14,6 +14,8 @@ A Added m_alias A Added support for XMLRPC queries A Added /botserv set msg A Added /operserv config +A Added /ns cert +A Added /operserv login F Changed the GHOST command to not allow ghosting unidentified users if the RECOVER command exists F Some failed logic in /operserv exception that prevents proper exceptions from being added F Fixed the anope_os_sxlines MySQL table and code to work after restarting diff --git a/docs/Changes.conf b/docs/Changes.conf index eaf99cdd4..b07b99ce1 100644 --- a/docs/Changes.conf +++ b/docs/Changes.conf @@ -6,11 +6,11 @@ chanserv:modules added cs_clone and cs_mode nickserv:suspendexpire and nickserv:forbidexpire added chanserv:suspendexpire and chanserv:forbidexpire added module added cs_entrymsg -nickserv:modules added ns_ajoin +nickserv:modules added ns_ajoin, ns_cert options:nomlock added log:target added globops nickserv:confirmemailchanges added -operserv:modules added os_config +operserv:modules added os_config, os_login ** MODIFIED CONFIGURATION DIRECTIVES ** operserv:notifications removed osglobal, osmode, oskick, osakill, ossnline, ossqline, osszline, osnoop, osjupe, getpass, setpass, forbid, drop diff --git a/include/account.h b/include/account.h index 635606f62..01ec082dd 100644 --- a/include/account.h +++ b/include/account.h @@ -156,29 +156,17 @@ class CoreExport NickCore : public Extensible, public Flags<NickCoreFlag, NI_END MemoInfo memos; uint16 channelcount; /* Number of channels currently registered */ - OperType *ot; + Oper *o; /* Unsaved data */ time_t lastmail; /* Last time this nick record got a mail */ std::list<NickAlias *> aliases; /* List of aliases */ - /** Check whether this opertype has access to run the given command string. - * @param cmdstr The string to check, e.g. botserv/set/private. - * @return True if this opertype may run the specified command, false otherwise. - */ - virtual bool HasCommand(const Anope::string &cmdstr) const; - /** 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; - /** Check whether this opertype has access to the given special permission. - * @param privstr The priv to check for, e.g. users/auspex. - * @return True if this opertype has the specified priv, false otherwise. - */ - virtual bool HasPriv(const Anope::string &privstr) const; - /** Add an entry to the nick's access list * * @param entry The nick!ident@host entry to add to the access list diff --git a/include/config.h b/include/config.h index 4a8d8411f..aee6f44e5 100644 --- a/include/config.h +++ b/include/config.h @@ -757,7 +757,7 @@ class CoreExport ServerConfig /* List of available opertypes */ std::list<OperType *> MyOperTypes; /* List of pairs of opers and their opertype from the config */ - std::list<std::pair<Anope::string, Anope::string> > Opers; + std::vector<Oper *> Opers; }; /** This class can be used on its own to represent an exception, or derived to represent a module-specific exception. diff --git a/include/opertype.h b/include/opertype.h index 6f48b7831..bf76d71eb 100644 --- a/include/opertype.h +++ b/include/opertype.h @@ -10,6 +10,25 @@ #include "hashcomp.h" +class OperType; + +struct Oper +{ + Anope::string name; + Anope::string password; + Anope::string certfp; + OperType *ot; + + Oper(const Anope::string &n, const Anope::string &p, const Anope::string &c, OperType *o) : + name(n), password(p), certfp(c), ot(o) { } + + /** Find an oper block by name + * @param name The name + * @return the oper block + */ + static Oper *Find(const Anope::string &name); +}; + class CoreExport OperType { private: @@ -36,6 +55,12 @@ class CoreExport OperType */ std::set<OperType *> inheritances; public: + /** Find an oper type by name + * @param name The name + * @return The oper type + */ + static OperType *Find(const Anope::string &name); + /** Create a new opertype of the given name. * @param nname The opertype name, e.g. "sra". */ diff --git a/include/users.h b/include/users.h index 30f5c8275..9f6e250e5 100644 --- a/include/users.h +++ b/include/users.h @@ -197,6 +197,23 @@ class CoreExport User : public Extensible */ virtual bool IsRecognized(bool CheckSecure = false); + /** Check if the user is a services oper + * @return true if they are an oper + */ + bool IsServicesOper(); + + /** Check whether this user has access to run the given command string. + * @param cmdstr The string to check, e.g. botserv/set/private. + * @return True if this user may run the specified command, false otherwise. + */ + bool HasCommand(const Anope::string &cmdstr); + + /** Check whether this user has access to the given special permission. + * @param privstr The priv to check for, e.g. users/auspex. + * @return True if this user has the specified priv, false otherwise. + */ + bool HasPriv(const Anope::string &privstr); + /** Update the last usermask stored for a user, and check to see if they are recognized */ void UpdateHost(); diff --git a/modules/core/bs_assign.cpp b/modules/core/bs_assign.cpp index d86a07c23..f1000cb11 100644 --- a/modules/core/bs_assign.cpp +++ b/modules/core/bs_assign.cpp @@ -41,13 +41,13 @@ class CommandBSAssign : public Command return MOD_CONT; } - if (ci->botflags.HasFlag(BS_NOBOT) || (!check_access(u, ci, CA_ASSIGN) && !u->Account()->HasPriv("botserv/administration"))) + if (ci->botflags.HasFlag(BS_NOBOT) || (!check_access(u, ci, CA_ASSIGN) && !u->HasPriv("botserv/administration"))) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; } - if (bi->HasFlag(BI_PRIVATE) && !u->Account()->HasCommand("botserv/assign/private")) + if (bi->HasFlag(BI_PRIVATE) && !u->HasCommand("botserv/assign/private")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; diff --git a/modules/core/bs_badwords.cpp b/modules/core/bs_badwords.cpp index 7de30afe2..5117055a3 100644 --- a/modules/core/bs_badwords.cpp +++ b/modules/core/bs_badwords.cpp @@ -58,7 +58,7 @@ class BadwordsDelCallback : public NumberList public: BadwordsDelCallback(CommandSource &_source, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), c(_c), Deleted(0), override(false) { - if (!check_access(source.u, source.ci, CA_BADWORDS) && source.u->Account()->HasPriv("botserv/administration")) + if (!check_access(source.u, source.ci, CA_BADWORDS) && source.u->HasPriv("botserv/administration")) this->override = true; } @@ -245,7 +245,7 @@ class CommandBSBadwords : public Command return MOD_CONT; } - if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !u->Account()->HasPriv("botserv/administration"))) + if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !u->HasPriv("botserv/administration"))) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; diff --git a/modules/core/bs_bot.cpp b/modules/core/bs_bot.cpp index 50812d0d0..d35d90ec1 100644 --- a/modules/core/bs_bot.cpp +++ b/modules/core/bs_bot.cpp @@ -321,7 +321,7 @@ class CommandBSBot : public Command if (cmd.equals_ci("ADD")) { // ADD nick user host real - 5 - if (!u->Account()->HasCommand("botserv/bot/add")) + if (!u->HasCommand("botserv/bot/add")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; @@ -344,7 +344,7 @@ class CommandBSBot : public Command { // CHANGE oldn newn user host real - 6 // but only oldn and newn are required - if (!u->Account()->HasCommand("botserv/bot/change")) + if (!u->HasCommand("botserv/bot/change")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; @@ -361,7 +361,7 @@ class CommandBSBot : public Command else if (cmd.equals_ci("DEL")) { // DEL nick - if (!u->Account()->HasCommand("botserv/bot/del")) + if (!u->HasCommand("botserv/bot/del")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; diff --git a/modules/core/bs_botlist.cpp b/modules/core/bs_botlist.cpp index b9c1f9287..bd2413b36 100644 --- a/modules/core/bs_botlist.cpp +++ b/modules/core/bs_botlist.cpp @@ -39,7 +39,7 @@ class CommandBSBotList : public Command } } - if (u->Account()->HasCommand("botserv/botlist") && count < BotListByNick.size()) + if (u->HasCommand("botserv/botlist") && count < BotListByNick.size()) { source.Reply(_("Bots reserved to IRC operators:")); diff --git a/modules/core/bs_help.cpp b/modules/core/bs_help.cpp index 7c0d2da70..f8fc414b5 100644 --- a/modules/core/bs_help.cpp +++ b/modules/core/bs_help.cpp @@ -41,7 +41,7 @@ class CommandBSHelp : public Command "%s HELP \037command\037\002."), BotServ->nick.c_str(), BotServ->nick.c_str(), BotServ->nick.c_str()); for (CommandMap::const_iterator it = BotServ->Commands.begin(), it_end = BotServ->Commands.end(); it != it_end; ++it) - if (!Config->HidePrivilegedCommands || it->second->permission.empty() || (u->Account() && u->Account()->HasCommand(it->second->permission))) + if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission)) it->second->OnServHelp(source); source.Reply(_("Bot will join a channel whenever there is at least\n" "\002%d\002 user(s) on it. Additionally, all %s commands\n" diff --git a/modules/core/bs_info.cpp b/modules/core/bs_info.cpp index 828a1bf2d..a5853f611 100644 --- a/modules/core/bs_info.cpp +++ b/modules/core/bs_info.cpp @@ -65,12 +65,12 @@ class CommandBSInfo : public Command source.Reply(_(" Options : %s"), bi->HasFlag(BI_PRIVATE) ? _("Private") : _("None")); source.Reply(_(" Used on : %d channel(s)"), bi->chancount); - if (u->Account()->HasPriv("botserv/administration")) + if (u->HasPriv("botserv/administration")) this->send_bot_channels(source, bi); } else if ((ci = cs_findchan(query))) { - if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("botserv/administration")) + if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("botserv/administration")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; diff --git a/modules/core/bs_kick.cpp b/modules/core/bs_kick.cpp index 7ca21f9ce..316b50be6 100644 --- a/modules/core/bs_kick.cpp +++ b/modules/core/bs_kick.cpp @@ -38,7 +38,7 @@ class CommandBSKick : public Command SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]")); else if (!value.equals_ci("ON") && !value.equals_ci("OFF")) SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]")); - else if (!check_access(u, ci, CA_SET) && !u->Account()->HasPriv("botserv/administration")) + else if (!check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration")) source.Reply(_(ACCESS_DENIED)); else if (!ci->bi) source.Reply(_(BOT_NOT_ASSIGNED)); diff --git a/modules/core/bs_set.cpp b/modules/core/bs_set.cpp index b149857d0..96a8c2b83 100644 --- a/modules/core/bs_set.cpp +++ b/modules/core/bs_set.cpp @@ -33,7 +33,7 @@ class CommandBSSet : public Command if (readonly) source.Reply(_("Sorry, bot option setting is temporarily disabled.")); - else if (u->Account()->HasCommand("botserv/set/private") && option.equals_ci("PRIVATE")) + else if (u->HasCommand("botserv/set/private") && option.equals_ci("PRIVATE")) { BotInfo *bi; @@ -59,7 +59,7 @@ class CommandBSSet : public Command } else if (!(ci = cs_findchan(chan))) source.Reply(_(CHAN_X_NOT_REGISTERED), chan.c_str()); - else if (!u->Account()->HasPriv("botserv/administration") && !check_access(u, ci, CA_SET)) + else if (!u->HasPriv("botserv/administration") && !check_access(u, ci, CA_SET)) source.Reply(_(ACCESS_DENIED)); else { @@ -126,7 +126,7 @@ class CommandBSSet : public Command else SyntaxError(source, "SET GREET", _("SET \037channel\037 GREET {\037ON|\037}")); } - else if (u->Account()->HasCommand("botserv/set/nobot") && option.equals_ci("NOBOT")) + else if (u->HasCommand("botserv/set/nobot") && option.equals_ci("NOBOT")) { if (value.equals_ci("ON")) { @@ -218,7 +218,7 @@ class CommandBSSet : public Command "Note: access to this command is controlled by the\n" "level SET."), BotServ->nick.c_str()); User *u = source.u; - if (u->Account() && u->Account()->IsServicesOper()) + if (u->IsServicesOper()) source.Reply(_("These options are reserved to Services Operators:\n" " \n" " NOBOT Prevent a bot from being assigned to \n" diff --git a/modules/core/bs_unassign.cpp b/modules/core/bs_unassign.cpp index 884939f84..f64cb526d 100644 --- a/modules/core/bs_unassign.cpp +++ b/modules/core/bs_unassign.cpp @@ -30,7 +30,7 @@ class CommandBSUnassign : public Command if (readonly) source.Reply(_(BOT_ASSIGN_READONLY)); - else if (!u->Account()->HasPriv("botserv/administration") && !check_access(u, ci, CA_ASSIGN)) + else if (!u->HasPriv("botserv/administration") && !check_access(u, ci, CA_ASSIGN)) source.Reply(_(ACCESS_DENIED)); else if (!ci->bi) source.Reply(_(BOT_NOT_ASSIGNED)); diff --git a/modules/core/cs_access.cpp b/modules/core/cs_access.cpp index d65f0b718..e2e2a946e 100644 --- a/modules/core/cs_access.cpp +++ b/modules/core/cs_access.cpp @@ -110,7 +110,7 @@ class AccessDelCallback : public NumberList public: AccessDelCallback(CommandSource &_source, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), c(_c), Deleted(0), Denied(false) { - if (!check_access(source.u, source.ci, CA_ACCESS_CHANGE) && source.u->Account()->HasPriv("chanserv/access/modify")) + if (!check_access(source.u, source.ci, CA_ACCESS_CHANGE) && source.u->HasPriv("chanserv/access/modify")) this->override = true; } @@ -143,7 +143,7 @@ class AccessDelCallback : public NumberList ChanAccess *u_access = ci->GetAccess(u); int16 u_level = u_access ? u_access->level : 0; - if (u_level <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) + if (u_level <= access->level && !u->HasPriv("chanserv/access/modify")) { Denied = true; return; @@ -179,7 +179,7 @@ class CommandCSAccess : public Command ChanAccess *u_access = ci->GetAccess(u); int16 u_level = u_access ? u_access->level : 0; - if (level >= u_level && !u->Account()->HasPriv("chanserv/access/modify")) + if (level >= u_level && !u->HasPriv("chanserv/access/modify")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; @@ -211,7 +211,7 @@ class CommandCSAccess : public Command if (access) { /* Don't allow lowering from a level >= u_level */ - if (access->level >= u_level && !u->Account()->HasPriv("chanserv/access/modify")) + if (access->level >= u_level && !u->HasPriv("chanserv/access/modify")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; @@ -267,7 +267,7 @@ class CommandCSAccess : public Command int16 u_level = u_access ? u_access->level : 0; if (!access) source.Reply(_("\002%s\002 not found on %s access list."), mask.c_str(), ci->name.c_str()); - else if (access->nc != u->Account() && check_access(u, ci, CA_NOJOIN) && u_level <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) + else if (access->nc != u->Account() && check_access(u, ci, CA_NOJOIN) && u_level <= access->level && !u->HasPriv("chanserv/access/modify")) source.Reply(_(ACCESS_DENIED)); else { @@ -373,7 +373,7 @@ class CommandCSAccess : public Command User *u = source.u; ChannelInfo *ci = source.ci; - if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify")) + if (!IsFounder(u, ci) && !u->HasPriv("chanserv/access/modify")) source.Reply(_(ACCESS_DENIED)); else { @@ -688,7 +688,7 @@ class CommandCSLevels : public Command this->OnSyntaxError(source, cmd); else if (ci->HasFlag(CI_XOP)) source.Reply(_("Levels are not available as xOP is enabled on this channel.")); - else if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify")) + else if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("chanserv/access/modify")) source.Reply(_(ACCESS_DENIED)); else if (cmd.equals_ci("SET")) this->DoSet(source, params); diff --git a/modules/core/cs_akick.cpp b/modules/core/cs_akick.cpp index 920dfc6f7..bad0e6d22 100644 --- a/modules/core/cs_akick.cpp +++ b/modules/core/cs_akick.cpp @@ -488,7 +488,7 @@ class CommandCSAKick : public Command if (mask.empty() && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL"))) this->OnSyntaxError(source, cmd); - else if (!check_access(u, ci, CA_AKICK) && !u->Account()->HasPriv("chanserv/access/modify")) + else if (!check_access(u, ci, CA_AKICK) && !u->HasPriv("chanserv/access/modify")) source.Reply(_(ACCESS_DENIED)); else if (!cmd.equals_ci("LIST") && !cmd.equals_ci("VIEW") && !cmd.equals_ci("ENFORCE") && readonly) source.Reply(_("Sorry, channel autokick list modification is temporarily disabled.")); diff --git a/modules/core/cs_clone.cpp b/modules/core/cs_clone.cpp index f816eb2f5..5b264c8df 100644 --- a/modules/core/cs_clone.cpp +++ b/modules/core/cs_clone.cpp @@ -47,7 +47,7 @@ public: return MOD_CONT; } - if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit")) + if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit")) { source.Reply(u->Account()->channelcount > Config->CSMaxReg ? _(CHAN_EXCEEDED_CHANNEL_LIMIT) : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg); return MOD_CONT; diff --git a/modules/core/cs_drop.cpp b/modules/core/cs_drop.cpp index 44e58693e..248cfa37e 100644 --- a/modules/core/cs_drop.cpp +++ b/modules/core/cs_drop.cpp @@ -38,19 +38,19 @@ class CommandCSDrop : public Command ci = cs_findchan(chan); - if (ci->HasFlag(CI_FORBIDDEN) && !u->Account()->HasCommand("chanserv/drop")) + if (ci->HasFlag(CI_FORBIDDEN) && !u->HasCommand("chanserv/drop")) { source.Reply(_(CHAN_X_FORBIDDEN), chan.c_str()); return MOD_CONT; } - if (ci->HasFlag(CI_SUSPENDED) && !u->Account()->HasCommand("chanserv/drop")) + if (ci->HasFlag(CI_SUSPENDED) && !u->HasCommand("chanserv/drop")) { source.Reply(_(CHAN_X_FORBIDDEN), chan.c_str()); return MOD_CONT; } - if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->Account()->HasCommand("chanserv/drop")) + if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->HasCommand("chanserv/drop")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; @@ -82,7 +82,7 @@ class CommandCSDrop : public Command bool OnHelp(CommandSource &source, const Anope::string &subcommand) { User *u = source.u; - if (u->Account() && u->Account()->IsServicesOper()) + if (u->IsServicesOper()) source.Reply(_("Syntax: \002DROP \037channel\037\002\n" " \n" "Unregisters the named channel. Only \002Services Operators\002\n" diff --git a/modules/core/cs_getkey.cpp b/modules/core/cs_getkey.cpp index e9b685a34..da71e690e 100644 --- a/modules/core/cs_getkey.cpp +++ b/modules/core/cs_getkey.cpp @@ -28,7 +28,7 @@ class CommandCSGetKey : public Command User *u = source.u; ChannelInfo *ci = source.ci; - if (!check_access(u, ci, CA_GETKEY) && !u->Account()->HasCommand("chanserv/getkey")) + if (!check_access(u, ci, CA_GETKEY) && !u->HasCommand("chanserv/getkey")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; diff --git a/modules/core/cs_help.cpp b/modules/core/cs_help.cpp index db34fc8ea..67b2354f9 100644 --- a/modules/core/cs_help.cpp +++ b/modules/core/cs_help.cpp @@ -42,13 +42,13 @@ class CommandCSHelp : public Command ChanServ->nick.c_str(), ChanServ->nick.c_str(), ChanServ->nick.c_str(), ChanServ->nick.c_str()); for (CommandMap::const_iterator it = ChanServ->Commands.begin(); it != ChanServ->Commands.end(); ++it) - if (!Config->HidePrivilegedCommands || it->second->permission.empty() || (u->Account() && u->Account()->HasCommand(it->second->permission))) + if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission)) it->second->OnServHelp(source); if (Config->CSExpire >= 86400) source.Reply(_("Note that any channel which is not used for %d days\n" "(i.e. which no user on the channel's access list enters\n" "for that period of time) will be automatically dropped."), Config->CSExpire / 86400); - if (u->Account() && u->Account()->IsServicesOper()) + if (u->IsServicesOper()) source.Reply(_(" \n" "Services Operators can also drop any channel without needing\n" "to identify via password, and may view the access, AKICK,\n" diff --git a/modules/core/cs_info.cpp b/modules/core/cs_info.cpp index a0b07d759..48baa67ae 100644 --- a/modules/core/cs_info.cpp +++ b/modules/core/cs_info.cpp @@ -42,7 +42,7 @@ class CommandCSInfo : public Command User *u = source.u; ChannelInfo *ci = source.ci; - bool has_auspex = u->IsIdentified() && u->Account()->HasPriv("chanserv/auspex"); + bool has_auspex = u->IsIdentified() && u->HasPriv("chanserv/auspex"); bool show_all = false; if (ci->HasFlag(CI_FORBIDDEN)) diff --git a/modules/core/cs_list.cpp b/modules/core/cs_list.cpp index 32894242b..8e3d75e5f 100644 --- a/modules/core/cs_list.cpp +++ b/modules/core/cs_list.cpp @@ -30,7 +30,7 @@ class CommandCSList : public Command Anope::string pattern = params[0]; unsigned nchans; char buf[BUFSIZE]; - bool is_servadmin = u->Account()->HasCommand("chanserv/list"); + bool is_servadmin = u->HasCommand("chanserv/list"); int count = 0, from = 0, to = 0; bool forbidden = false, suspended = false, channoexpire = false; diff --git a/modules/core/cs_mode.cpp b/modules/core/cs_mode.cpp index 209ee751f..55da9762c 100644 --- a/modules/core/cs_mode.cpp +++ b/modules/core/cs_mode.cpp @@ -314,7 +314,7 @@ class CommandCSMode : public Command if (!ci || !ci->c) source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str()); - else if (!check_access(u, ci, CA_MODE) && !u->Account()->HasCommand("chanserv/mode")) + else if (!check_access(u, ci, CA_MODE) && !u->HasCommand("chanserv/mode")) source.Reply(_(ACCESS_DENIED)); else if (subcommand.equals_ci("LOCK")) this->DoLock(source, params); diff --git a/modules/core/cs_register.cpp b/modules/core/cs_register.cpp index 995c0e65b..13aa17d35 100644 --- a/modules/core/cs_register.cpp +++ b/modules/core/cs_register.cpp @@ -45,7 +45,7 @@ class CommandCSRegister : public Command source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str()); else if (c && !c->HasUserStatus(u, CMODE_OP)) source.Reply(_("You must be a channel operator to register the channel.")); - else if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit")) + else if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit")) source.Reply(u->Account()->channelcount > Config->CSMaxReg ? _(CHAN_EXCEEDED_CHANNEL_LIMIT) : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg); else { diff --git a/modules/core/cs_set_founder.cpp b/modules/core/cs_set_founder.cpp index b6f7dab95..200d32e95 100644 --- a/modules/core/cs_set_founder.cpp +++ b/modules/core/cs_set_founder.cpp @@ -49,7 +49,7 @@ class CommandCSSetFounder : public Command } nc = na->nc; - if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit")) + if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit")) { source.Reply(_("\002%s\002 has too many channels registered."), na->nick.c_str()); return MOD_CONT; diff --git a/modules/core/cs_topic.cpp b/modules/core/cs_topic.cpp index 9798a12c0..8fd23f7f1 100644 --- a/modules/core/cs_topic.cpp +++ b/modules/core/cs_topic.cpp @@ -31,7 +31,7 @@ class CommandCSTopic : public Command if (!c) source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str()); - else if (!check_access(u, ci, CA_TOPIC) && !u->Account()->HasCommand("chanserv/topic")) + else if (!check_access(u, ci, CA_TOPIC) && !u->HasCommand("chanserv/topic")) source.Reply(_(ACCESS_DENIED)); else { diff --git a/modules/core/cs_xop.cpp b/modules/core/cs_xop.cpp index b556e210e..38c82d183 100644 --- a/modules/core/cs_xop.cpp +++ b/modules/core/cs_xop.cpp @@ -131,7 +131,7 @@ class XOPBase : public Command ChanAccess *access = ci->GetAccess(u); uint16 ulev = access ? access->level : 0; - if ((level >= ulev || ulev < ACCESS_AOP) && !u->Account()->HasPriv("chanserv/access/modify")) + if ((level >= ulev || ulev < ACCESS_AOP) && !u->HasPriv("chanserv/access/modify")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; @@ -152,7 +152,7 @@ class XOPBase : public Command /** * Patch provided by PopCorn to prevert AOP's reducing SOP's levels **/ - if (access->level >= ulev && !u->Account()->HasPriv("chanserv/access/modify")) + if (access->level >= ulev && !u->HasPriv("chanserv/access/modify")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; @@ -220,7 +220,7 @@ class XOPBase : public Command ChanAccess *access = ci->GetAccess(u); uint16 ulev = access ? access->level : 0; - if ((!access || access->nc != u->Account()) && (level >= ulev || ulev < ACCESS_AOP) && !u->Account()->HasPriv("chanserv/access/modify")) + if ((!access || access->nc != u->Account()) && (level >= ulev || ulev < ACCESS_AOP) && !u->HasPriv("chanserv/access/modify")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; @@ -242,7 +242,7 @@ class XOPBase : public Command } else { - if (access->nc != u->Account() && ulev <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) + if (access->nc != u->Account() && ulev <= access->level && !u->HasPriv("chanserv/access/modify")) source.Reply(_(ACCESS_DENIED)); else { @@ -270,7 +270,7 @@ class XOPBase : public Command ChanAccess *access = ci->GetAccess(u); uint16 ulev = access ? access->level : 0; - if (!ulev && !u->Account()->HasCommand("chanserv/access/list")) + if (!ulev && !u->HasCommand("chanserv/access/list")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; @@ -336,7 +336,7 @@ class XOPBase : public Command return MOD_CONT; } - if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify")) + if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("chanserv/access/modify")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; diff --git a/modules/core/hs_help.cpp b/modules/core/hs_help.cpp index 35d2b99cb..c360376c7 100644 --- a/modules/core/hs_help.cpp +++ b/modules/core/hs_help.cpp @@ -32,7 +32,7 @@ class CommandHSHelp : public Command User *u = source.u; source.Reply(_("%s commands"), Config->s_HostServ.c_str()); for (CommandMap::const_iterator it = HostServ->Commands.begin(), it_end = HostServ->Commands.end(); it != it_end; ++it) - if (!Config->HidePrivilegedCommands || it->second->permission.empty() || (u->Account() && u->Account()->HasCommand(it->second->permission))) + if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission)) it->second->OnServHelp(source); } }; diff --git a/modules/core/ms_help.cpp b/modules/core/ms_help.cpp index c27f1791b..54210e4fe 100644 --- a/modules/core/ms_help.cpp +++ b/modules/core/ms_help.cpp @@ -37,7 +37,7 @@ class CommandMSHelp : public Command "registered in order to send a memo.\n" "%s's commands include:"), MemoServ->nick.c_str(), MemoServ->nick.c_str()); for (CommandMap::const_iterator it = MemoServ->Commands.begin(), it_end = MemoServ->Commands.end(); it != it_end; ++it) - if (!Config->HidePrivilegedCommands || it->second->permission.empty() || (u->Account() && u->Account()->HasCommand(it->second->permission))) + if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission)) it->second->OnServHelp(source); source.Reply(_("Type \002%R%s HELP \037command\037\002 for help on any of the\n" "above commands.\n" diff --git a/modules/core/ms_info.cpp b/modules/core/ms_info.cpp index af0dddd21..f87b8af60 100644 --- a/modules/core/ms_info.cpp +++ b/modules/core/ms_info.cpp @@ -31,7 +31,7 @@ class CommandMSInfo : public Command const Anope::string &nname = !params.empty() ? params[0] : ""; int hardmax = 0; - if (!nname.empty() && nname[0] != '#' && u->Account()->HasPriv("memoserv/info")) + if (!nname.empty() && nname[0] != '#' && u->HasPriv("memoserv/info")) { na = findnick(nname); if (!na) @@ -159,14 +159,14 @@ class CommandMSInfo : public Command if (!mi->memomax) { - if (!u->Account()->IsServicesOper() && hardmax) + if (!u->IsServicesOper() && hardmax) source.Reply(_("Your memo limit is \0020\002; you will not receive any new memos. You cannot change this limit.")); else source.Reply(_("Your memo limit is \0020\002; you will not receive any new memos.")); } else if (mi->memomax > 0) { - if (!u->Account()->IsServicesOper() && hardmax) + if (!u->IsServicesOper() && hardmax) source.Reply(_("Your memo limit is \002%d\002, and may not be changed."), mi->memomax); else source.Reply(_("Your memo limit is \002%d\002."), mi->memomax); @@ -190,7 +190,7 @@ class CommandMSInfo : public Command bool OnHelp(CommandSource &source, const Anope::string &subcommand) { User *u = source.u; - if (u->Account() && u->Account()->IsServicesOper()) + if (u->IsServicesOper()) source.Reply(_("Syntax: \002INFO [\037nick\037 | \037channel\037]\002\n" "Without a parameter, displays information on the number of\n" "memos you have, how many of them are unread, and how many\n" diff --git a/modules/core/ms_rsend.cpp b/modules/core/ms_rsend.cpp index 98d7aaba4..7e6af4950 100644 --- a/modules/core/ms_rsend.cpp +++ b/modules/core/ms_rsend.cpp @@ -39,7 +39,7 @@ class CommandMSRSend : public Command if (Config->MSMemoReceipt == 1) { /* Services opers and above can use rsend */ - if (u->Account()->IsServicesOper()) + if (u->IsServicesOper()) memo_send(source, nick, text, 3); else source.Reply(_(ACCESS_DENIED)); diff --git a/modules/core/ms_set.cpp b/modules/core/ms_set.cpp index ecd436079..82524551d 100644 --- a/modules/core/ms_set.cpp +++ b/modules/core/ms_set.cpp @@ -78,7 +78,7 @@ class CommandMSSet : public Command int16 limit; NickCore *nc = u->Account(); ChannelInfo *ci = NULL; - bool is_servadmin = u->Account()->HasPriv("memoserv/set-limit"); + bool is_servadmin = u->HasPriv("memoserv/set-limit"); if (p1[0] == '#') { @@ -258,7 +258,7 @@ class CommandMSSet : public Command else if (subcommand.equals_ci("LIMIT")) { User *u = source.u; - if (u->Account() && u->Account()->IsServicesOper()) + if (u->IsServicesOper()) source.Reply(_("Syntax: \002SET LIMIT [\037user\037 | \037channel\037] {\037limit\037 | NONE} [HARD]\002\n" " \n" "Sets the maximum number of memos a user or channel is\n" diff --git a/modules/core/ns_access.cpp b/modules/core/ns_access.cpp index 57cc5f4f2..c3c46297c 100644 --- a/modules/core/ns_access.cpp +++ b/modules/core/ns_access.cpp @@ -127,7 +127,7 @@ class CommandNSAccess : public Command const Anope::string &mask = params.size() > 1 ? params[1] : ""; NickAlias *na; - if (cmd.equals_ci("LIST") && u->Account()->IsServicesOper() && !mask.empty() && (na = findnick(params[1]))) + if (cmd.equals_ci("LIST") && u->IsServicesOper() && !mask.empty() && (na = findnick(params[1]))) return this->DoServAdminList(source, params, na->nc); if (!mask.empty() && mask.find('@') == Anope::string::npos) diff --git a/modules/core/ns_alist.cpp b/modules/core/ns_alist.cpp index b2a622c2d..f0fd3f7aa 100644 --- a/modules/core/ns_alist.cpp +++ b/modules/core/ns_alist.cpp @@ -36,7 +36,7 @@ class CommandNSAList : public Command Anope::string nick; NickAlias *na; - int is_servadmin = u->Account()->IsServicesOper(); + int is_servadmin = u->IsServicesOper(); unsigned lev_param = 0; if (!is_servadmin) @@ -134,7 +134,7 @@ class CommandNSAList : public Command bool OnHelp(CommandSource &source, const Anope::string &subcommand) { User *u = source.u; - if (u->Account() && u->Account()->IsServicesOper()) + if (u->IsServicesOper()) source.Reply(_("Syntax: \002ALIST [\037nickname\037] [\037level\037]\002\n" " \n" "With no parameters, lists channels you have access on. With\n" diff --git a/modules/core/ns_cert.cpp b/modules/core/ns_cert.cpp index 5581149f6..5604f680d 100644 --- a/modules/core/ns_cert.cpp +++ b/modules/core/ns_cert.cpp @@ -134,7 +134,7 @@ class CommandNSCert : public Command const Anope::string &mask = params.size() > 1 ? params[1] : ""; NickAlias *na; - if (cmd.equals_ci("LIST") && u->Account()->IsServicesOper() && !mask.empty() && (na = findnick(mask))) + if (cmd.equals_ci("LIST") && u->IsServicesOper() && !mask.empty() && (na = findnick(mask))) return this->DoServAdminList(source, na->nc); if (u->Account()->HasFlag(NI_SUSPENDED)) diff --git a/modules/core/ns_drop.cpp b/modules/core/ns_drop.cpp index 4729bf8d8..2cd134bd2 100644 --- a/modules/core/ns_drop.cpp +++ b/modules/core/ns_drop.cpp @@ -51,7 +51,7 @@ class CommandNSDrop : public Command if (is_mine && nick.empty()) my_nick = na->nick; - if (!is_mine && !u->Account()->HasPriv("nickserv/drop")) + if (!is_mine && !u->HasPriv("nickserv/drop")) source.Reply(_(ACCESS_DENIED)); else if (Config->NSSecureAdmins && !is_mine && na->nc->IsServicesOper()) source.Reply(_(ACCESS_DENIED)); @@ -90,7 +90,7 @@ class CommandNSDrop : public Command bool OnHelp(CommandSource &source, const Anope::string &subcommand) { User *u = source.u; - if (u->Account() && u->Account()->HasPriv("nickserv/drop")) + if (u->Account() && u->HasPriv("nickserv/drop")) source.Reply(_("Syntax: \002DROP [\037nickname\037]\002\n" " \n" "Without a parameter, drops your nickname from the\n" diff --git a/modules/core/ns_group.cpp b/modules/core/ns_group.cpp index 3aa4b6419..0e51ded66 100644 --- a/modules/core/ns_group.cpp +++ b/modules/core/ns_group.cpp @@ -42,12 +42,16 @@ class CommandNSGroup : public Command } if (Config->RestrictOperNicks) - for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it) - if (!u->HasMode(UMODE_OPER) && u->nick.find_ci(it->first) != Anope::string::npos) + for (unsigned i = 0; i < Config->Opers.size(); ++i) + { + Oper *o = Config->Opers[i]; + + if (!u->HasMode(UMODE_OPER) && u->nick.find_ci(o->name) != Anope::string::npos) { source.Reply(_(NICK_CANNOT_BE_REGISTERED), u->nick.c_str()); return MOD_CONT; } + } NickAlias *target, *na = findnick(u->nick); if (!(target = findnick(nick))) @@ -255,7 +259,7 @@ class CommandNSGList : public Command const NickCore *nc = u->Account(); - if (!nick.empty() && (!nick.equals_ci(u->nick) && !u->Account()->IsServicesOper())) + if (!nick.empty() && (!nick.equals_ci(u->nick) && !u->IsServicesOper())) source.Reply(_(ACCESS_DENIED), Config->s_NickServ.c_str()); else if (!nick.empty() && (!findnick(nick) || !(nc = findnick(nick)->nc))) source.Reply(nick.empty() ? _(NICK_NOT_REGISTERED) : _(NICK_X_NOT_REGISTERED), nick.c_str()); @@ -276,7 +280,7 @@ class CommandNSGList : public Command bool OnHelp(CommandSource &source, const Anope::string &subcommand) { User *u = source.u; - if (u->Account() && u->Account()->IsServicesOper()) + if (u->IsServicesOper()) source.Reply(_("Syntax: \002GLIST [\037nickname\037]\002\n" " \n" "Without a parameter, lists all nicknames that are in\n" diff --git a/modules/core/ns_help.cpp b/modules/core/ns_help.cpp index bb16f5594..94442606e 100644 --- a/modules/core/ns_help.cpp +++ b/modules/core/ns_help.cpp @@ -38,9 +38,9 @@ class CommandNSHelp : public Command "\002%R%s HELP \037command\037\002."), NickServ->nick.c_str(), NickServ->nick.c_str(), NickServ->nick.c_str()); for (CommandMap::const_iterator it = NickServ->Commands.begin(), it_end = NickServ->Commands.end(); it != it_end; ++it) - if (!Config->HidePrivilegedCommands || it->second->permission.empty() || (u->Account() && u->Account()->HasCommand(it->second->permission))) + if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission)) it->second->OnServHelp(source); - if (u->Account() && u->Account()->IsServicesOper()) + if (u->IsServicesOper()) source.Reply(_(" \n" "Services Operators can also drop any nickname without needing\n" "to identify for the nick, and may view the access list for\n" diff --git a/modules/core/ns_info.cpp b/modules/core/ns_info.cpp index 4c25179a4..6328341cb 100644 --- a/modules/core/ns_info.cpp +++ b/modules/core/ns_info.cpp @@ -40,7 +40,7 @@ class CommandNSInfo : public Command const Anope::string &nick = params[0]; NickAlias *na = findnick(nick); - bool has_auspex = u->IsIdentified() && u->Account()->HasPriv("nickserv/auspex"); + bool has_auspex = u->IsIdentified() && u->HasPriv("nickserv/auspex"); if (!na) { @@ -71,7 +71,7 @@ class CommandNSInfo : public Command source.Reply(_("%s is %s"), na->nick.c_str(), na->last_realname.c_str()); if (na->nc->IsServicesOper() && (show_hidden || !na->nc->HasFlag(NI_HIDE_STATUS))) - source.Reply(_("%s is a services operator of type %s."), na->nick.c_str(), na->nc->ot->GetName().c_str()); + source.Reply(_("%s is a services operator of type %s."), na->nick.c_str(), na->nc->o->ot->GetName().c_str()); if (nick_online) { diff --git a/modules/core/ns_list.cpp b/modules/core/ns_list.cpp index 64eef0983..1f48d2f01 100644 --- a/modules/core/ns_list.cpp +++ b/modules/core/ns_list.cpp @@ -43,7 +43,7 @@ class CommandNSList : public Command const NickCore *mync; unsigned nnicks; char buf[BUFSIZE]; - bool is_servadmin = u->Account()->IsServicesOper(); + bool is_servadmin = u->IsServicesOper(); char noexpire_char = ' '; int count = 0, from = 0, to = 0; bool suspended, nsnoexpire, forbidden, unconfirmed; @@ -151,7 +151,7 @@ class CommandNSList : public Command bool OnHelp(CommandSource &source, const Anope::string &subcommand) { User *u = source.u; - if (u->Account() && u->Account()->IsServicesOper()) + if (u->IsServicesOper()) source.Reply(_("Syntax: \002LIST \037pattern\037 [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]\002\n" " \n" "Lists all registered nicknames which match the given\n" @@ -202,7 +202,7 @@ class CommandNSList : public Command void OnSyntaxError(CommandSource &source, const Anope::string &subcommand) { User *u = source.u; - if (u->Account()->IsServicesOper()) + if (u->IsServicesOper()) SyntaxError(source, "LIST", _("LIST \037pattern\037 [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]")); else SyntaxError(source, "LIST", _(NICK_LIST_SYNTAX)); diff --git a/modules/core/ns_logout.cpp b/modules/core/ns_logout.cpp index 798cda80f..c074fecf8 100644 --- a/modules/core/ns_logout.cpp +++ b/modules/core/ns_logout.cpp @@ -29,11 +29,11 @@ class CommandNSLogout : public Command const Anope::string ¶m = params.size() > 1 ? params[1] : ""; User *u2; - if (!u->Account()->IsServicesOper() && !nick.empty()) + if (!u->IsServicesOper() && !nick.empty()) this->OnSyntaxError(source, ""); else if (!(u2 = (!nick.empty() ? finduser(nick) : u))) source.Reply(_(NICK_X_NOT_IN_USE), nick.c_str()); - else if (!nick.empty() && u2->Account() && !u2->Account()->IsServicesOper()) + else if (!nick.empty() && !u2->IsServicesOper()) source.Reply(_("You can't logout %s because they are a Services Operator."), nick.c_str()); else { @@ -64,7 +64,7 @@ class CommandNSLogout : public Command bool OnHelp(CommandSource &source, const Anope::string &subcommand) { User *u = source.u; - if (u->Account() && u->Account()->IsServicesOper()) + if (u->IsServicesOper()) source.Reply(_("Syntax: \002LOGOUT [\037nickname\037 [REVALIDATE]]\002\n" " \n" "Without a parameter, reverses the effect of the \002IDENTIFY\002 \n" diff --git a/modules/core/ns_register.cpp b/modules/core/ns_register.cpp index 1cf690f79..531933340 100644 --- a/modules/core/ns_register.cpp +++ b/modules/core/ns_register.cpp @@ -29,7 +29,7 @@ class CommandNSConfirm : public Command User *u = source.u; const Anope::string &passcode = params[0]; - if (u->Account() && u->Account()->HasPriv("nickserv/confirm")) + if (u->Account() && u->HasPriv("nickserv/confirm")) { NickAlias *na = findnick(passcode); if (na == NULL) @@ -74,7 +74,7 @@ class CommandNSConfirm : public Command " \n" "This is also used after the RESETPASS command has been used to\n" "force identify you to your nick so you may change your password.")); - if (u->Account() && u->Account()->HasPriv("nickserv/confirm")) + if (u->Account() && u->HasPriv("nickserv/confirm")) source.Reply(_("Additionally, Services Operators with the \037nickserv/confirm\037 permission can\n" "replace \037passcode\037 with a users nick to force validate them.")); return true; @@ -134,16 +134,16 @@ class CommandNSRegister : public Command } if (Config->RestrictOperNicks) - for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it) + for (unsigned i = 0; i < Config->Opers.size(); ++i) { - Anope::string nick = it->first; + Oper *o = Config->Opers[i]; - if (u->nick.find_ci(nick) != Anope::string::npos && !u->HasMode(UMODE_OPER)) + if (!u->HasMode(UMODE_OPER) && u->nick.find_ci(o->name) != Anope::string::npos) { source.Reply(_(NICK_CANNOT_BE_REGISTERED), u->nick.c_str()); return MOD_CONT; } - } + } if (Config->NSForceEmail && email.empty()) this->OnSyntaxError(source, ""); diff --git a/modules/core/ns_resetpass.cpp b/modules/core/ns_resetpass.cpp index 09dea3502..70c7dbb6a 100644 --- a/modules/core/ns_resetpass.cpp +++ b/modules/core/ns_resetpass.cpp @@ -29,7 +29,7 @@ class CommandNSResetPass : public Command User *u = source.u; NickAlias *na; - if (Config->RestrictMail && (!u->Account() || !u->Account()->HasCommand("nickserv/resetpass"))) + if (Config->RestrictMail && (!u->Account() || !u->HasCommand("nickserv/resetpass"))) source.Reply(_(ACCESS_DENIED)); else if (!(na = findnick(params[0]))) source.Reply(_(NICK_X_NOT_REGISTERED), params[0].c_str()); diff --git a/modules/core/ns_sendpass.cpp b/modules/core/ns_sendpass.cpp index 4dc571dfe..9614211c1 100644 --- a/modules/core/ns_sendpass.cpp +++ b/modules/core/ns_sendpass.cpp @@ -30,7 +30,7 @@ class CommandNSSendPass : public Command const Anope::string &nick = params[0]; NickAlias *na; - if (Config->RestrictMail && (!u->Account() || !u->Account()->HasCommand("nickserv/sendpass"))) + if (Config->RestrictMail && (!u->Account() || !u->HasCommand("nickserv/sendpass"))) source.Reply(_(ACCESS_DENIED)); else if (!(na = findnick(nick))) source.Reply(_(NICK_X_NOT_REGISTERED), nick.c_str()); diff --git a/modules/core/ns_set_email.cpp b/modules/core/ns_set_email.cpp index 1c1836665..2d1d371f5 100644 --- a/modules/core/ns_set_email.cpp +++ b/modules/core/ns_set_email.cpp @@ -80,7 +80,7 @@ class CommandNSSetEmail : public Command return MOD_CONT; } - if (!param.empty() && Config->NSConfirmEmailChanges && !u->Account()->IsServicesOper()) + if (!param.empty() && Config->NSConfirmEmailChanges && !u->IsServicesOper()) { u->Account()->Extend("ns_set_email", new ExtensibleItemRegular<Anope::string>(param)); Anope::string old = u->Account()->email; diff --git a/modules/core/os_help.cpp b/modules/core/os_help.cpp index f455b9079..e58eee435 100644 --- a/modules/core/os_help.cpp +++ b/modules/core/os_help.cpp @@ -31,7 +31,7 @@ class CommandOSHelp : public Command User *u = source.u; source.Reply(_("%s commands:"), OperServ->nick.c_str()); for (CommandMap::const_iterator it = OperServ->Commands.begin(), it_end = OperServ->Commands.end(); it != it_end; ++it) - if (!Config->HidePrivilegedCommands || it->second->permission.empty() || (u->Account() && u->Account()->HasCommand(it->second->permission))) + if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission)) it->second->OnServHelp(source); source.Reply(_("\002Notice:\002 All commands sent to %s are logged!"), OperServ->nick.c_str()); } diff --git a/modules/core/os_login.cpp b/modules/core/os_login.cpp new file mode 100644 index 000000000..fe2da3aac --- /dev/null +++ b/modules/core/os_login.cpp @@ -0,0 +1,82 @@ +/* OperServ core functions + * + * (C) 2003-2011 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandOSLogin : public Command +{ + public: + CommandOSLogin() : Command("LOGIN", 1, 1) + { + this->SetDesc(Anope::printf(_("Login to %s"), OperServ->nick.c_str())); + } + + CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) + { + const Anope::string &password = params[0]; + + Oper *o = source.u->Account()->o; + if (o == NULL) + source.Reply(_("No oper block for your nick.")); + else if (o->password.empty()) + source.Reply(_("Your oper block doesn't require logging in.")); + else if (source.u->GetExt("os_login_password_correct")) + source.Reply(_("You are already identified.")); + else if (o->password != password) + { + source.Reply(_(PASSWORD_INCORRECT)); + if (bad_password(source.u)) + return MOD_STOP; + } + else + { + Log(LOG_ADMIN, source.u, this) << "and succesfully identified to " << OperServ->nick; + source.u->Extend("os_login_password_correct"); + source.Reply(_("Password accepted.")); + } + + return MOD_CONT; + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) + { + source.Reply(_("Syntax: \002LOGIN\002 \037password\037\n" + " \n" + "Logs you in to %s so you gain Services Operator privileges.\n" + "This command may be unnecessary if your oper block is\n" + "configured without a password."), OperServ->nick.c_str()); + return true; + } + + void OnSyntaxError(CommandSource &source, const Anope::string &subcommand) + { + SyntaxError(source, "LOGIN", _("LOGIN \037password\037")); + } +}; + +class OSLogin : public Module +{ + CommandOSLogin commandoslogin; + + public: + OSLogin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetType(CORE); + + this->AddCommand(OperServ, &commandoslogin); + } +}; + +MODULE_INIT(OSLogin) diff --git a/modules/core/os_staff.cpp b/modules/core/os_staff.cpp index 7e8a4f86d..f2dbc7613 100644 --- a/modules/core/os_staff.cpp +++ b/modules/core/os_staff.cpp @@ -25,11 +25,11 @@ class CommandOSStaff : public Command { source.Reply(_("On Level Nick")); - for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it) + for (unsigned i = 0; i < Config->Opers.size(); ++i) { - Anope::string nick = it->first, type = it->second; + Oper *o = Config->Opers[i]; - NickAlias *na = findnick(nick); + NickAlias *na = findnick(o->name); if (na) { NickCore *nc = na->nc; @@ -38,12 +38,12 @@ class CommandOSStaff : public Command User *u2 = *uit; if (na->nick.equals_ci(u2->nick)) - source.Reply(_(" %c %s %s"), '*', type.c_str(), u2->nick.c_str()); + source.Reply(_(" %c %s %s"), '*', o->ot->GetName().c_str(), u2->nick.c_str()); else - source.Reply(_(" %c %s %s [%s]"), '*', type.c_str(), na->nick.c_str(), u2->nick.c_str()); + source.Reply(_(" %c %s %s [%s]"), '*', o->ot->GetName().c_str(), na->nick.c_str(), u2->nick.c_str()); } if (nc->Users.empty()) - source.Reply(_(" %c %s %s"), ' ', type.c_str(), na->nick.c_str()); + source.Reply(_(" %c %s %s"), ' ', o->ot->GetName().c_str(), na->nick.c_str()); } } diff --git a/modules/extra/cs_entrymsg.cpp b/modules/extra/cs_entrymsg.cpp index df68b141f..649fd69f8 100644 --- a/modules/extra/cs_entrymsg.cpp +++ b/modules/extra/cs_entrymsg.cpp @@ -107,7 +107,7 @@ class CommandEntryMessage : public Command User *u = source.u; ChannelInfo *ci = source.ci; - if (ci && (IsFounder(u, ci) || u->Account()->HasCommand("chanserv/entrymsg"))) + if (ci && (IsFounder(u, ci) || u->HasCommand("chanserv/entrymsg"))) { bool success = true; if (params[1].equals_ci("LIST")) diff --git a/modules/extra/db_mysql.cpp b/modules/extra/db_mysql.cpp index 7b1addbdb..d8a6d934c 100644 --- a/modules/extra/db_mysql.cpp +++ b/modules/extra/db_mysql.cpp @@ -663,7 +663,7 @@ class DBMySQL : public Module if (service == NickServ) { - if (u->Account() && ((command->name.equals_ci("SET") && !params.empty()) || (command->name.equals_ci("SASET") && u->Account()->HasCommand("nickserv/saset") && params.size() > 1))) + if (u->Account() && ((command->name.equals_ci("SET") && !params.empty()) || (command->name.equals_ci("SASET") && u->HasCommand("nickserv/saset") && params.size() > 1))) { Anope::string cmd = (command->name.equals_ci("SET") ? params[0] : params[1]); NickCore *nc = (command->name.equals_ci("SET") ? u->Account() : findcore(params[0])); @@ -697,7 +697,7 @@ class DBMySQL : public Module { if (!ci) return; - if (!u->Account()->HasPriv("chanserv/set") && check_access(u, ci, CA_SET)) + if (!u->HasPriv("chanserv/set") && check_access(u, ci, CA_SET)) return; if (params[1].equals_ci("FOUNDER") && ci->founder) { @@ -727,7 +727,7 @@ class DBMySQL : public Module { if (!ci) return; - if (!check_access(u, ci, CA_SET) && !u->Account()->HasPriv("botserv/administration")) + if (!check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration")) return; if (params[1].equals_ci("BADWORDS") || params[1].equals_ci("BOLDS") || params[1].equals_ci("CAPS") || params[1].equals_ci("COLORS") || params[1].equals_ci("FLOOD") || params[1].equals_ci("REPEAT") || params[1].equals_ci("REVERSES") || params[1].equals_ci("UNDERLINES")) { @@ -756,12 +756,12 @@ class DBMySQL : public Module } else if (command->name.equals_ci("SET") && params.size() > 2) { - if (ci && !check_access(u, ci, CA_SET) && !u->Account()->HasPriv("botserv/administration")) + if (ci && !check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration")) return; BotInfo *bi = NULL; if (!ci) bi = findbot(params[0]); - if (bi && params[1].equals_ci("PRIVATE") && u->Account()->HasPriv("botserv/set/private")) + if (bi && params[1].equals_ci("PRIVATE") && u->HasPriv("botserv/set/private")) { this->RunQuery("UPDATE `anope_bs_core` SET `flags` = '" + ToString(bi->ToString()) + "' WHERE `nick` = '" + this->Escape(bi->nick) + "'"); } diff --git a/modules/extra/hs_request.cpp b/modules/extra/hs_request.cpp index 3b0a3c4cf..4978035d3 100644 --- a/modules/extra/hs_request.cpp +++ b/modules/extra/hs_request.cpp @@ -423,12 +423,17 @@ void req_send_memos(CommandSource &source, const Anope::string &vIdent, const An host = vHost; if (HSRequestMemoOper == 1) - for (it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it) + for (unsigned i = 0; i < Config->Opers.size(); ++i) { - Anope::string nick = it->first; + Oper *o = Config->Opers[i]; + + NickAlias *na = findnick(o->name); + if (!na) + continue; + char message[BUFSIZE]; snprintf(message, sizeof(message), _("[auto memo] vHost \002%s\002 has been requested."), host.c_str()); - memo_send(source, nick, message, 2); + memo_send(source, na->nick, message, 2); } } diff --git a/modules/extra/m_async_commands.cpp b/modules/extra/m_async_commands.cpp index e7aa37ff0..7e1b24f34 100644 --- a/modules/extra/m_async_commands.cpp +++ b/modules/extra/m_async_commands.cpp @@ -46,7 +46,7 @@ class AsynchCommandMutex : public CommandMutex return; } - if (!command->permission.empty() && !u->Account()->HasCommand(command->permission)) + if (!command->permission.empty() && !u->HasCommand(command->permission)) { u->SendMessage(bi, _(ACCESS_DENIED)); Log(LOG_COMMAND, "denied", bi) << "Access denied for user " << u->GetMask() << " with command " << command; diff --git a/modules/extra/m_ldap_oper.cpp b/modules/extra/m_ldap_oper.cpp index 8a5f57116..b8a1d5f51 100644 --- a/modules/extra/m_ldap_oper.cpp +++ b/modules/extra/m_ldap_oper.cpp @@ -1,6 +1,7 @@ #include "module.h" #include "ldap.h" +static std::set<Oper *> my_opers; static Anope::string opertype_attribute; class IdentifyInterface : public LDAPInterface @@ -36,22 +37,32 @@ class IdentifyInterface : public LDAPInterface const Anope::string &opertype = attr.get(opertype_attribute); - for (std::list<OperType *>::iterator oit = Config->MyOperTypes.begin(), oit_end = Config->MyOperTypes.end(); oit != oit_end; ++oit) + OperType *ot = OperType::Find(opertype); + if (ot != NULL && (u->Account()->o == NULL || ot != u->Account()->o->ot)) { - OperType *ot = *oit; - if (ot->GetName() == opertype && ot != u->Account()->ot) + Oper *o = u->Account()->o; + if (o != NULL && my_opers.count(o) > 0) { - u->Account()->ot = ot; - Log() << "m_ldap_oper: Tied " << u->nick << " (" << u->Account()->display << ") to opertype " << ot->GetName(); - break; + my_opers.erase(o); + delete o; } + o = new Oper(u->nick, "", "", ot); + my_opers.insert(o); + u->Account()->o = o; + Log() << "m_ldap_oper: Tied " << u->nick << " (" << u->Account()->display << ") to opertype " << ot->GetName(); } } catch (const LDAPException &ex) { - if (u->Account()->ot != NULL) + if (u->Account()->o != NULL) { - u->Account()->ot = NULL; + if (my_opers.count(u->Account()->o) > 0) + { + my_opers.erase(u->Account()->o); + delete u->Account()->o; + } + u->Account()->o = NULL; + Log() << "m_ldap_oper: Removed services operator from " << u->nick << " (" << u->Account()->display << ")"; } } @@ -79,8 +90,8 @@ class LDAPOper : public Module this->SetAuthor("Anope"); this->SetType(SUPPORTED); - Implementation i[] = { I_OnReload, I_OnNickIdentify }; - ModuleManager::Attach(i, this, 2); + Implementation i[] = { I_OnReload, I_OnNickIdentify, I_OnDelCore }; + ModuleManager::Attach(i, this, 3); OnReload(false); } @@ -94,6 +105,10 @@ class LDAPOper : public Module this->basedn = config.ReadValue("m_ldap_oper", "basedn", "", 0); this->filter = config.ReadValue("m_ldap_oper", "filter", "", 0); opertype_attribute = config.ReadValue("m_ldap_oper", "opertype_attribute", "", 0); + + for (std::set<Oper *>::iterator it = my_opers.begin(), it_end = my_opers.end(); it != it_end; ++it) + delete *it; + my_opers.clear(); } void OnNickIdentify(User *u) @@ -115,6 +130,16 @@ class LDAPOper : public Module Log() << "m_ldapoper: " << ex.GetReason(); } } + + void OnDelCore(NickCore *nc) + { + if (nc->o != NULL && my_opers.count(nc->o) > 0) + { + my_opers.erase(nc->o); + delete nc->o; + nc->o = NULL; + } + } }; MODULE_INIT(LDAPOper) diff --git a/modules/extra/m_xmlrpc_main.cpp b/modules/extra/m_xmlrpc_main.cpp index 39c4cca19..4efe230ad 100644 --- a/modules/extra/m_xmlrpc_main.cpp +++ b/modules/extra/m_xmlrpc_main.cpp @@ -248,8 +248,8 @@ class MyXMLRPCEvent : public XMLRPCEvent if (u->Account()) { request->reply("account", iface->Sanitize(u->Account()->display)); - if (u->Account()->ot) - request->reply("opertype", iface->Sanitize(u->Account()->ot->GetName())); + if (u->Account()->o) + request->reply("opertype", iface->Sanitize(u->Account()->o->ot->GetName())); } Anope::string channels; diff --git a/src/commands.cpp b/src/commands.cpp index 00fe6574c..91b4787fd 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -156,7 +156,7 @@ void mod_run_cmd(BotInfo *bi, User *u, ChannelInfo *ci, Command *c, const Anope: } // If the command requires a permission, and they aren't registered or don't have the required perm, DENIED - if (!c->permission.empty() && !u->Account()->HasCommand(c->permission)) + if (!c->permission.empty() && !u->HasCommand(c->permission)) { u->SendMessage(bi, _(ACCESS_DENIED)); Log(LOG_COMMAND, "denied", bi) << "Access denied for user " << u->GetMask() << " with command " << command; @@ -201,7 +201,7 @@ void mod_help_cmd(BotInfo *bi, User *u, ChannelInfo *ci, const Anope::string &cm source.service = ci ? ci->bi : bi; source.fantasy = ci != NULL; - if (!c || (Config->HidePrivilegedCommands && !c->permission.empty() && (!u->Account() || !u->Account()->HasCommand(c->permission))) || !c->OnHelp(source, subcommand)) + if (!c || (Config->HidePrivilegedCommands && !c->permission.empty() && !u->HasCommand(c->permission)) || !c->OnHelp(source, subcommand)) source.Reply( _("No help available for \002%s\002."), cmd.c_str()); else { @@ -215,7 +215,7 @@ void mod_help_cmd(BotInfo *bi, User *u, ChannelInfo *ci, const Anope::string &cm if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !u->IsIdentified()) source.Reply( _("You need to be identified to use this command.")); /* User doesn't have the proper permission to use this command */ - else if (!c->permission.empty() && (!u->Account() || !u->Account()->HasCommand(c->permission))) + else if (!c->permission.empty() && !u->HasCommand(c->permission)) source.Reply(_("You cannot use this command.")); /* User can use this command */ else diff --git a/src/config.cpp b/src/config.cpp index 86ef446bc..e230a15b7 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -792,8 +792,10 @@ static bool DoneOperTypes(ServerConfig *, const Anope::string &) static bool InitOpers(ServerConfig *config, const Anope::string &) { for (nickcore_map::const_iterator it = NickCoreList.begin(), it_end = NickCoreList.end(); it != it_end; ++it) - it->second->ot = NULL; + it->second->o = NULL; + for (unsigned i = 0; i < config->Opers.size(); ++i) + delete config->Opers[i]; config->Opers.clear(); return true; @@ -803,6 +805,8 @@ static bool DoOper(ServerConfig *config, const Anope::string &, const Anope::str { Anope::string name = values[0].GetValue(); Anope::string type = values[1].GetValue(); + Anope::string password = values[2].GetValue(); + Anope::string certfp = values[3].GetValue(); ValueItem vi(name); if (!ValidateNotEmpty(config, "oper", "name", vi)) @@ -811,35 +815,35 @@ static bool DoOper(ServerConfig *config, const Anope::string &, const Anope::str ValueItem vi2(type); if (!ValidateNotEmpty(config, "oper", "type", vi2)) throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information."); + + OperType *ot = NULL; + for (std::list<OperType *>::iterator it = config->MyOperTypes.begin(), it_end = config->MyOperTypes.end(); it != it_end; ++it) + if ((*it)->GetName() == type) + ot = *it; + if (ot == NULL) + throw ConfigException("Oper block for " + name + " has invalid oper type " + type); + + Oper *o = new Oper(name, password, certfp, ot); + config->Opers.push_back(o); - config->Opers.push_back(std::make_pair(name, type)); return true; } static bool DoneOpers(ServerConfig *config, const Anope::string &) { - for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = config->Opers.begin(), it_end = config->Opers.end(); it != it_end; ++it) + for (unsigned i = 0; i < config->Opers.size(); ++i) { - Anope::string nick = it->first, type = it->second; + Oper *o = config->Opers[i]; - NickAlias *na = findnick(nick); + NickAlias *na = findnick(o->name); if (!na) // Nonexistant nick continue; - if (!na->nc) - throw CoreException("Nick with no core?"); - - for (std::list<OperType *>::iterator tit = config->MyOperTypes.begin(), tit_end = config->MyOperTypes.end(); tit != tit_end; ++tit) - { - OperType *ot = *tit; - if (ot->GetName().equals_ci(type)) - { - Log() << "Tied oper " << na->nc->display << " to type " << type; - na->nc->ot = ot; - } - } + na->nc->o = o; + Log() << "Tied oper " << na->nc->display << " to type " << o->ot->GetName(); } + return true; } @@ -1295,9 +1299,9 @@ ConfigItems::ConfigItems(ServerConfig *conf) {DT_CHARPTR, DT_CHARPTR, DT_CHARPTR, DT_CHARPTR}, InitOperTypes, DoOperType, DoneOperTypes}, {"oper", - {"name", "type", ""}, - {"", "", ""}, - {DT_CHARPTR, DT_CHARPTR}, + {"name", "type", "password", "certfp", ""}, + {"", "", "", "", ""}, + {DT_CHARPTR, DT_CHARPTR, DT_CHARPTR, DT_CHARPTR}, InitOpers, DoOper, DoneOpers}, {"", {""}, diff --git a/src/memoserv.cpp b/src/memoserv.cpp index 128694557..9869e4264 100644 --- a/src/memoserv.cpp +++ b/src/memoserv.cpp @@ -167,7 +167,7 @@ void memo_send(CommandSource &source, const Anope::string &name, const Anope::st bool ischan, isforbid; MemoInfo *mi; Anope::string sender = u && u->Account() ? u->Account()->display : ""; - int is_servoper = u && u->Account() && u->Account()->IsServicesOper(); + bool is_servoper = u != NULL && u->IsServicesOper(); if (readonly) u->SendMessage(MemoServ, _(MEMO_SEND_DISABLED)); @@ -217,7 +217,7 @@ void memo_send(CommandSource &source, const Anope::string &name, const Anope::st { if (!z || z == 3) source.Reply(_("Memo sent to \002%s\002."), name.c_str()); - if ((!u->Account() || !u->Account()->IsServicesOper()) && mi->HasIgnore(u)) + if (!u->IsServicesOper() && mi->HasIgnore(u)) return; u->lastmemosend = Anope::CurTime; diff --git a/src/messages.cpp b/src/messages.cpp index c5ea2f039..192859e6f 100644 --- a/src/messages.cpp +++ b/src/messages.cpp @@ -37,15 +37,13 @@ bool OnStats(const Anope::string &source, const std::vector<Anope::string> ¶ ircdproto->SendNumeric(Config->ServerName, 219, source, "%c :End of /STATS report.", params[0][0]); else { - std::list<std::pair<Anope::string, Anope::string> >::iterator it, it_end; - - for (it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it) + for (unsigned i = 0; i < Config->Opers.size(); ++i) { - Anope::string nick = it->first, type = it->second; + Oper *o = Config->Opers[i]; - NickCore *nc = findcore(nick); - if (nc) - ircdproto->SendNumeric(Config->ServerName, 243, source, "O * * %s %s 0", nick.c_str(), type.c_str()); + NickAlias *na = findnick(o->name); + if (na) + ircdproto->SendNumeric(Config->ServerName, 243, source, "O * * %s %s 0", o->name.c_str(), o->ot->GetName().c_str()); } ircdproto->SendNumeric(Config->ServerName, 219, source, "%c :End of /STATS report.", params[0][0]); diff --git a/src/nickalias.cpp b/src/nickalias.cpp index 3c8af1142..06e5f60dd 100644 --- a/src/nickalias.cpp +++ b/src/nickalias.cpp @@ -19,24 +19,12 @@ NickAlias::NickAlias(const Anope::string &nickname, NickCore *nickcore) : Flags< NickAliasList[this->nick] = this; - for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it) + if (this->nc->o == NULL) { - if (this->nc->ot) - break; - if (!this->nick.equals_ci(it->first)) - continue; - - for (std::list<OperType *>::iterator tit = Config->MyOperTypes.begin(), tit_end = Config->MyOperTypes.end(); tit != tit_end; ++tit) - { - OperType *ot = *tit; - - if (ot->GetName().equals_ci(it->second)) - { - Log() << "Tied oper " << this->nc->display << " to type " << ot->GetName(); - this->nc->ot = ot; - break; - } - } + Oper *o = Oper::Find(this->nick); + if (o == NULL) + o = Oper::Find(this->nc->display); + this->nc->o = o; } } diff --git a/src/nickcore.cpp b/src/nickcore.cpp index e83d46c47..5fdf9c2dd 100644 --- a/src/nickcore.cpp +++ b/src/nickcore.cpp @@ -9,7 +9,7 @@ NickCore::NickCore(const Anope::string &coredisplay) : Flags<NickCoreFlag, NI_EN if (coredisplay.empty()) throw CoreException("Empty display passed to NickCore constructor"); - this->ot = NULL; + this->o = NULL; this->channelcount = 0; this->lastmail = 0; this->memos.memomax = Config->MSMaxMemos; @@ -65,30 +65,9 @@ NickCore::~NickCore() } } -bool NickCore::HasCommand(const Anope::string &cmdstr) const -{ - if (!this->ot) - // No opertype. - return false; - - return this->ot->HasCommand(cmdstr); -} - bool NickCore::IsServicesOper() const { - if (this->ot) - return true; - - return false; -} - -bool NickCore::HasPriv(const Anope::string &privstr) const -{ - if (!this->ot) - // No opertype. - return false; - - return this->ot->HasPriv(privstr); + return this->o != NULL; } void NickCore::AddAccess(const Anope::string &entry) diff --git a/src/nickserv.cpp b/src/nickserv.cpp index fb1e52819..0c036f564 100644 --- a/src/nickserv.cpp +++ b/src/nickserv.cpp @@ -185,12 +185,14 @@ int validate_user(User *u) u->Collide(na); return 0; } + if (!u->IsIdentified() && !u->fingerprint.empty() && na->nc->FindCert(u->fingerprint)) { u->SendMessage(NickServ, _("SSL Fingerprint accepted, you are now identified")); u->Identify(na); return 1; } + if (!na->nc->HasFlag(NI_SECURE) && u->IsRecognized()) { na->last_seen = Anope::CurTime; diff --git a/src/opertype.cpp b/src/opertype.cpp index 19e0dd00f..9d6a4086f 100644 --- a/src/opertype.cpp +++ b/src/opertype.cpp @@ -7,6 +7,33 @@ #include "services.h" + +Oper *Oper::Find(const Anope::string &name) +{ + for (unsigned i = 0; i < Config->Opers.size(); ++i) + { + Oper *o = Config->Opers[i]; + + if (o->name.equals_ci(name)) + return o; + } + + return NULL; +} + +OperType *OperType::Find(const Anope::string &name) +{ + for (std::list<OperType *>::iterator it = Config->MyOperTypes.begin(), it_end = Config->MyOperTypes.end(); it != it_end; ++it) + { + OperType *ot = *it; + + if (ot->GetName() == name) + return ot; + } + + return NULL; +} + OperType::OperType(const Anope::string &nname) : name(nname) { } diff --git a/src/users.cpp b/src/users.cpp index 4b6e7368e..5e97fee5d 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -462,6 +462,46 @@ bool User::IsRecognized(bool CheckSecure) return OnAccess; } +/** Check if the user is a services oper + * @return true if they are an oper + */ +bool User::IsServicesOper() +{ + if (!this->nc || !this->nc->o) + // No opertype. + return false; + else if (!this->nc->o->certfp.empty() && this->fingerprint != this->nc->o->certfp) + // Certfp mismatch + return false; + else if (!this->nc->o->password.empty() && !this->GetExt("os_login_password_correct")) + // Not identified + return false; + + return true; +} + +/** Check whether this user has access to run the given command string. + * @param cmdstr The string to check, e.g. botserv/set/private. + * @return True if this user may run the specified command, false otherwise. + */ +bool User::HasCommand(const Anope::string &command) +{ + if (this->IsServicesOper()) + return this->nc->o->ot->HasCommand(command); + return false; +} + +/** Check whether this user has access to the given special permission. + * @param privstr The priv to check for, e.g. users/auspex. + * @return True if this user has the specified priv, false otherwise. + */ +bool User::HasPriv(const Anope::string &priv) +{ + if (this->IsServicesOper()) + return this->nc->o->ot->HasPriv(priv); + return false; +} + /** Update the last usermask stored for a user, and check to see if they are recognized */ void User::UpdateHost() |